#javascript #arrays #object
#javascript #массивы #объект
Вопрос:
Я хочу создать массив со значением uniqueDate в моем массиве. Итак, если у меня есть этот массив:
const arr = [
{
name: "Edward",
date: "24 March"
},
{
name: "Banana",
date: "12 March"
},
{
name: "Edward",
date: "23 March"
},
{
name: "Edward",
date: "23 March"
}
]
… тогда результат будет примерно таким:
[
{name:"Edward", uniqueDate: 2, totalSubmit: 3},
{nama: "Banana",uniqueDate: 1, totalSubmit: 1}
]
Первая уникальная дата равна 2, потому что у нас 2 разные даты: 24 марта и 23 марта. Я пытался использовать reduce
, но у него есть некоторые проблемы.
Комментарии:
1. Пожалуйста, покажите нам, что вы уже пробовали.
2. Например, у меня есть этот массив: const arr = [ { нама: «Эдвард», дата: «24 марта» }, { нама: «Банан», дата: «12 марта» }, { нама: «Эдвард», дата: «23 марта» }, { нама: «Эдвард», дата: «23 марта» }, { нама: «Боб», дата: «1 марта» }, { нама: «Пэм», дата: «1 марта» }, {нама: «Анна», дата: «19 марта» }, { нама: «Джейк», дата: «12 марта» } ]
3. Я уменьшил его в два раза, const reducedSales = arr.reduce((acc, item) => { var previousItem = acc.find(FindItem => (FindItem[‘nama’] === item[‘nama’]) amp;amp; (FindItem[‘date’] === item[‘date’])); // если предыдущий элемент имеет значение false, то это означает, что другой распространитель Nama if (!previousItem) { acc.push({…item, totalSubmit: 1 }) } else { previousItem.totalSubmit } возвращает acc; }, [])
4. и еще одно сокращение, const update = reducedSales.reduce((acc, item) => { var previousItem = acc.find(FindItem => FindItem[‘nama’] === item[‘nama’]); // если предыдущий элемент имеет значение false, то это означает, что другой распространитель Nama, если (!previousItem) { acc.push({…item, hariKerja: 1 }) } else { previousItem.hariKerja } возвращает acc; }, []) console.log(обновление)
5. @AndrewL64 это выходные данные: [ { нама: ‘Эдвард’, дата: ’24 марта’, итоговая отправка: 1, Харикерджа: 2 }, { нама: ‘Банан’, дата: ’12 марта’, итоговая отправка: 1, Харикерджа: 1 }, { нама: ‘Боб’, дата: ‘1 марта’, Итоговая отправка: 1, Харикерджа: 1 }, { нама: ‘Пэм’, дата: ‘1 марта’, Итоговая отправка: 1, Харикерджа: 1 }, { нама: ‘Анна’, дата: ’19 марта’, Итоговая отправка: 1, Харикерджа:1 }, { нама: ‘Джейк’, дата: ’12 марта’, Итоговая отправка: 1, Харикерджа: 1 } ]
Ответ №1:
Вы можете использовать a Map
для сбора дат, которые идут с именем (проверьте правильность написания в примере данных!), А затем вы можете перебирать эти записи карты, чтобы получить как длину массива дат, так и количество уникальных (через Set):
const arr = [{name: "Edward",date: "24 March"},{name: "Banana",date: "12 March"},{name: "Edward",date: "23 March"},{name: "Edward",date: "23 March"}];
let map = new Map(arr.map(o => [o.name, []]));
for (let {name, date} of arr) map.get(name).push(date);
let result = Array.from(map.entries(), ([name, dates]) =>
({name, uniqueDate: new Set(dates).size, totalSubmit: dates.length})
);
console.log(result);
Если имя свойства, по которому нужно сгруппировать, содержит специальные символы, такие как пробел, то:
const arr = [{"Full Name": "Edward",date: "24 March"},{"Full Name": "Banana",date: "12 March"},{"Full Name": "Edward",date: "23 March"},{"Full Name": "Edward",date: "23 March"}];
let map = new Map(arr.map(o => [o["Full Name"], []]));
for (let o of arr) map.get(o["Full Name"]).push(o.date);
let result = Array.from(map.entries(), ([name, dates]) =>
({"Full Name": name, uniqueDate: new Set(dates).size, totalSubmit: dates.length})
);
console.log(result);
Комментарии:
1. Привет, большое спасибо за вашу помощь. Если я могу добавить еще 1 вопрос, что, если в имени моего объекта есть пробел? Например, вместо имени имя объекта является полным именем. Вместо даты имя объекта «Создано в».
2. для (пусть {name, date} arr) map.get(name).push(date); Ошибка типа: не удается прочитать свойство ‘push’ неопределенного значения, поэтому для контекста имя моего объекта выглядит как «Полное имя» и «Создано в».
3. Таким образом, фактический массив выглядит примерно так: const arr = [{«Полное имя»: «Эдвард»,»Создано в»: «24 марта»}]; и т. Д
4. См. Дополнение к ответу.
Ответ №2:
Вы можете вызвать функцию reduce, чтобы затем создать пару ключ-значение для каждого имени, где оно содержит имя, a Set
уникальных дат и totalSubmit . Наконец, вы можете получить значения этого объекта и сопоставить его с размером уникальных дат.
const arr = [{ name: "Edward", date: "24 March" }, { name: "Banana", date: "12 March" }, { name: "Edward", date: "23 March" }, { name: "Edward", date: "23 March" }];
const temp = arr.reduce((acc, { name, date }) => {
acc[name] = acc[name] || { name, dates: new Set(), totalSubmit: 0 };
acc[name].totalSubmit ;
acc[name].dates.add(date);
return acc;
}, {});
const result = Object.values(temp).map(({ name, dates, totalSubmit}) => ({ name, uniqueDate: dates.size, totalSubmit }));
console.log(result);
Комментарии:
1. Большое спасибо за ваш ответ! Могу я добавить еще 1 вопрос? Что, если в имени моего объекта есть пробел? Пример: вместо «name» его «Полное имя»
2. @EdwardTanoto Я предполагаю, что это «Полное имя» будет уникальным. в этом случае мы можем использовать key = name.split(‘ ‘).join(‘_’), который превращает
Edward Tanoto
вEdward_Tanoto