#javascript #arrays #filter
Вопрос:
У меня есть массив, подобный этому:
let data = [
{
name: 'foo',
score: 10,
},
{
name: 'bar',
score: 20
},
{
name: 'foo',
score: 15,
},
];
Теперь это представляет собой список результатов, набранных игроком. Я хочу получить наивысший балл от каждого игрока. Как я могу этого достичь? Я пробовал разные комбинации фильтров и не могу найти способ, не повторяя несколько раз массив.
Ответ №1:
Вы можете использовать reduce
для этого.
const highScores = data.reduce((memo, entry) => {
if (!memo[entry.name] || memo[entry.name] < entry.score) {
memo[entry.name]=entry.score
}
return memo;
},{})
Ответ №2:
Reduce()
идеально подходит для такого рода вещей.
let data = [{
name: 'foo',
score: 10,
},
{
name: 'bar',
score: 20
},
{
name: 'foo',
score: 15,
},
];
let hs = data.reduce((b, a) => {
let i = b.findIndex(e => e.name === a.name)
if (i > -1) b[i].score = Math.max(b[i].score, a.score)
else b.push(a)
return b;
}, []);
console.log(hs)
Ответ №3:
Я бы предложил что-то вроде этого:
const data = [
{
name: 'foo',
score: 10,
},
{
name: 'bar',
score: 20
},
{
name: 'foo',
score: 15,
},
];
// We'll keep track of the max scores here
const maxScore = {};
// Iterating with destructuring to directly access name/score
for (const { name, score } of data) {
const currentScore = maxScore[name];
if (!currentScore) {
// No score saved yet, save this one
maxScore[name] = score;
} else if (currentScore < score) {
// This score is higher than the saved one
maxScore[name] = score;
} else {
// Score is lower (or equal) so do nothing
}
}
console.log(maxScore);
// If you want to convert it back to an array:
const list = Object.entries(maxScore).map(
// Object.entries returns [key, value][]
// so we map it, extract the key/value (name/score) from each
// pair and create an object from it which we return
([name, score]) => ({ name, score }));
console.log(list);
Ответ №4:
let data = [
{
name: "foo",
score: 10,
},
{ name: "bar",
score: 20 },
{
name: "foo",
score: 15,
},
];
const highestIndex = data.reduce(result, {name, score}) => {
result[name] = !result[name] || score > result[name]
? score
: result[name];
return resu<
}, {})
если вам нужен результат в той же структуре, что и данные, просто преобразуйте результат
в массив с помощью сопоставления Object.entries:
const highestScores =
Object
.entries(highestIndex)
.map(([name, score]) => ({name, score}))
Ответ №5:
Вы можете решить эту проблему с reduce()
помощью или вы можете использовать классический шаблон решения.
С уменьшением()
const data = [{ name: 'foo', score: 10 }, { name: 'bar', score: 20 }, { name: 'foo', score: 15 } ];
const highsObj = data.reduce((acc, currentItem) => {
if (!acc[currentItem.name] || acc[currentItem.name].score < currentItem.score) {
acc[currentItem.name] = currentItem;
}
return acc;
}, {})
// As an array
const highsArray = Object.values(highsObj);
console.log(highsArray);
Классический узор
const data = [{ name: 'foo', score: 10 }, { name: 'bar', score: 20 }, { name: 'foo', score: 15 } ];
const highScores = {};
for (const item of data) {
const { name, score } = item;
const currentValue = highScores[name];
if (!currentValue || currentValue.score < score) {
highScores[name] = item;
}
}
// As an array
const highScoresArray = Object.values(highScores);
console.log(highScoresArray);
Ответ №6:
В чем проблема с перебором массива для начала? Бог не убивает котенка каждый раз , когда вы решаете проблему в JavaScript без вызова array.filter
или array.reduce
, вы знаете 🙂
Вот еще одно восхитительно нечистое решение (извините, кошечки, ничего личного), использующее удивительную пластичность JavaScript (использование объекта, такого как ассоциативный массив).
var data = [
{ name: 'foo', score: 10 },
{ name: 'bar', score: 20 },
{ name: 'foo', score: 15 },
];
var high_score = {};
for (record of data) { // note it's the ES6 "of", not the ill-fated legacy "in" !!!
if ((high_score[record.name] ?? 0) < record.score) {
high_score[record.name] = record.score;
}
}
// "high_score" is just an object with a property named after each player
console.log(high_score)
>>> Object { foo: 15, bar: 20 }
// This object can be accessed like an associative array (a circa 1995
// ancestor of a dictionary, if you like), in a pretty intuitive way:
console.log(high_score["foo"])
>>> 15
console.log(high_score["bar"])
>>> 20