我在 JavaScript 中有这个二维数组:
['Daniela', 'Jonas', 'Simon', 'Vincent']
['0', '3', '0', '4']
其中数字代表用户猜测随机数的次数。 我希望它看起来像这样:
['Jonas', 'Vincent', 'Simon', 'Daniela']
['3', '4', '0', '0']
所以基本上,按数字从低到高排序(除了 0,因为用户没有完成他的跑步),但是名字是根据数字排序的。
这怎么可能?
我试过像二维数组一样对它进行排序,但没有用,我尝试拆分不同的数组并手动对它们进行排序,但后来我不知道如何对它们进行连接排序。
如果你喜欢保留数组,你可以获取一个索引数组,按值排序,最后用索引映射两个数组。
let names = ['Daniela', 'Jonas', 'Simon', 'Vincent'],
values = ['0', '3', '0', '4'],
indices = [...values.keys()].sort((a, b) =>
(+values[a] || Number.MAX_VALUE) - (+values[b] || Number.MAX_VALUE)
);
[names, values] = [names, values].map(a => indices.map(i => a[i]));
console.log(...names);
console.log(...values);
正如@Roko 所建议的,在这种特殊情况下,对象数组是首选,因为它有助于使排序功能更容易。
但是,如果那根本不可能,我们可以手动压缩它们:
const zipped = users.map(
(user, index) => ({ name: user, guesses: Number(guesses[index]) })
);
然后,我们根据他们的猜测对他们进行排序。请注意我如何使用 Infinity 作为排序值 if
user.guesses === 0
.
zipped.sort(
(user1, user2) => (user1.guesses || Infinity) - (user2.guesses || Infinity)
);
但是,没有说明未完成测试的用户顺序如何。因此,假设它们的顺序被保留。
试一试(我将
zipped
分离回两个数组,以防万一你需要它们):
const users = ['Daniela', 'Jonas', 'Simon', 'Vincent'];
const guesses = ['0', '3', '0', '4'];
const zipped = users.map(
(user, index) => ({ name: user, guesses: Number(guesses[index]) })
);
zipped.sort(
(user1, user2) => (user1.guesses || Infinity) - (user2.guesses || Infinity)
);
console.log(zipped);
const [sortedUsers, sortedGuesses] = zipped.reduce(
([sortedUsers, sortedGuesses], currentUser) => [
[...sortedUsers, currentUser.name],
[...sortedGuesses, currentUser.guesses],
], [[], []]
);
console.log(sortedUsers, sortedGuesses);
将原始数组映射成对,如
[['0', 'Daniela'], ...]
。然后按数字排序,将零视为始终排在最后的特殊情况。然后使用 reduce 将这些对映射回原始的 2D 数组格式。
const arr = [['Daniela', 'Jonas', 'Simon', 'Vincent'],
['0', '3', '0', '4']]
console.log(arr[0].map((e,i)=>[arr[1][i],e])
.sort(([a],[b])=>((a==0)-(b==0) || a-b))
.reduce((a,[x,y])=>(a[0].push(y),a[1].push(x),a),[[],[]]))
zip
功能的完美用例:
let zip = (...a) => a[0].map((_, i) => a.map(r => r[i]))
//
let names = ['Daniela', 'Jonas', 'Simon', 'Vincent']
let scores = [0, 3, 0, 4]
let temp = zip(scores, names);
temp.sort((x, y) => (x[0] || Infinity) - (y[0] || Infinity));
[scores, names] = zip(...temp);
console.log(...names)
console.log(...scores)