#javascript #arrays
#javascript #массивы
Вопрос:
const current = [
{ studentName: 'Name', ItemNumber: 1, Score: 0 },
{ studentName: 'Name', ItemNumber: 2, Score: 1 }]
const needed = [
{ studentName: 'Name', Item1Score: 0, Item2Score: 1 }
]
const names = [...new Set(current.map(v=>v.studentName))]
const items = [...new Set(current.map(v=>v.ItemNumber))].length
Как я могу преобразовать текущий массив в тот, который мне нужен? Я знаю, как получить отдельные имена учащихся и количество элементов, но я не знаю, как эффективно объединить эту информацию, чтобы получить необходимый массив.
Комментарии:
1. Что вы пытаетесь сделать?
2. в конечном итоге я буду использовать новый массив (требуется константа) как часть таблицы данных: material-ui.com/components/data-grid
Ответ №1:
Сначала вы захотите собрать всех учащихся по имени, а затем начать комбинировать свойства на основе этого ItemNumber
const current = [
{ studentName: 'Name', ItemNumber: 1, Score: 0 },
{ studentName: 'Name', ItemNumber: 2, Score: 1 }]
const map = current.reduce((map, { studentName, ItemNumber, ...props }) => {
// collect by studentName
return map.set(studentName, {
...(map.get(studentName) ?? {}), // merge any previously found entries
...Object.fromEntries(Object.entries(props).map(([ key, val ]) =>
[ `Item${ItemNumber}${key}`, val ]))
})
}, new Map())
const needed = Array.from(map, ([ studentName, data ]) => ({
studentName,
...data
}))
console.info(needed)
Это принимает любое свойство, которое не studentName
является or ItemNumber
, и добавляет к нему префикс «Item<ItemNumber>», поэтому, если у вас есть другие свойства Score
, это также будет работать для них.
Комментарии:
1. это отличный ответ, поскольку он выходит за рамки требований. Теперь я могу получить доступ ко всем значениям, связанным с учеником, а не только к баллам по пунктам 1 и 2.
2. один дополнительный вопрос: как бы вы отредактировали ответ, чтобы разрешить агрегирование всех баллов для каждого учащегося, чтобы необходимый массив теперь выглядел следующим образом: const needed = [ { studentName: ‘Name’, totalScore: 1, Item1Score: 0, Item2Score: 1 } ]
Ответ №2:
Используется Array.reduce()
для создания объекта словаря из обоих наборов оценок, на которые ссылается имя учащегося. Затем преобразуйте объект словаря в массив объектов в запрошенном формате, используя комбинацию Object.entries()
и Array.map()
.
const current = [
{ studentName: 'Name', ItemNumber: 1, Score: 0 },
{ studentName: 'Name', ItemNumber: 2, Score: 1 }];
const neededDict = current.reduce((acc, {studentName, ItemNumber, Score})=>{
acc[studentName][`item${ItemNumber}Score`] = Score;
}), {});
const needed = Object.entries(neededDict).map(([key, value])=>{
return {
studentName: key,
Item1Score: value.Item1Score,
Item2Score: value.Item2Score
};
}
console.log(needed);