В качестве примера
у меня есть два массива
const tempData = [
{ day: "Mon", temp: 33.6 },
{ day: "Tue", temp: 34.6 },
{ day: "Wed", temp: 33.1 },
{ day: "Fri", temp: 35.6 }
];
const coughData = [
{ day: "Mon", count: 2 },
{ day: "Wed", count: 1 },
{ day: "Thur", count: 1 },
{ day: "Fri", count: 3 },
{ day: "Sat", count: 1 }
];
Мне нужно объединить эти массивы в один, чтобы, если день совпадает, значение счетчика добавлялось к этому объекту, если оно не соответствовало, оно добавляло оба объекта в массив.
Не знаю, если объяснение не так ясно, но
Ожидаемый результат должен быть таким:
const data = [
{ day: "Mon", temp: 33.6, count: 2 },
{ day: "Tue", temp: 34.6 },
{ day: "Wed", temp: 33.1, count: 1 },
{ day: "Thur", count: 1 },
{ day: "Fri", temp: 35.6, count: 3 },
{ day: "Sat", count: 1 }
];
Я пытаюсь использовать функцию карты, но не могу понять, как вернуть оба объекта, если они не совпадают:
const data = tempData.map(temp => {
coughData.map(cough => {
if (temp.day === cough.day) {
return (temp.count = cough.count);
} else {
return cough;
}
});
return temp;
});
Вы можете использовать функцию JavaScript Object.assign(). Метод Object.assign() используется для копирования значений всех перечисляемых свойств одного или нескольких исходных объектов в целевой объект. Этот метод вернет целевой объект
Вот так:
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.info(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.info(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Вы можете собрать все данные, сгруппированные по day
, в объект и получить значения в качестве набора результатов.
const
addToCollection = (collection, key) => o => Object.assign(collection[o[key]] ??= {}, o),
tempData = [{ day: "Mon", temp: 33.6 }, { day: "Tue", temp: 34.6 }, { day: "Wed", temp: 33.1 }, { day: "Fri", temp: 35.6 }],
coughData = [{ day: "Mon", count: 2 }, { day: "Wed", count: 1 }, { day: "Thur", count: 1 }, { day: "Fri", count: 3 }, { day: "Sat", count: 1 }],
collection = {};
tempData.forEach(addToCollection(collection, 'day'));
coughData.forEach(addToCollection(collection, 'day'));
console.info(Object.values(collection));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Вы можете сначала объединить объекты массивов, а затем использовать .reduce() вместе с Map для накопления значений. Карта может быть отмечена свойством day
, что позволит вам сгруппировать свойства связанных объектов вместе. Затем вы можете использовать Array.from(), чтобы преобразовать вашу карту обратно в массив объектов, например так:
const tempData = [{ day: "Mon", temp: 33.6 }, { day: "Tue", temp: 34.6 }, { day: "Wed", temp: 33.1 }, { day: "Fri", temp: 35.6 }];
const coughData = [{ day: "Mon", count: 2 }, { day: "Wed", count: 1 }, { day: "Thur", count: 1 }, { day: "Fri", count: 3 }, { day: "Sat", count: 1 }];
const arr = [...tempData, ...coughData];
const result = Array.from(arr.reduce((map, {day, ...rest}) => {
const seen = map.get(day) || {day};
return map.set(day, {...seen, ...rest});
}, new Map).values());
console.info(result);
Если вы добавите ключ day
вместо пустого литерала объекта здесь: map.get(day) || { day }
, вы можете получить Array.from(mapFromReduce.values())
. Нет необходимости в дополнительной операции ([day, obj]) => ({day, ...obj})
@adiga Хорошо, так намного лучше, спасибо :D
let newArray = Array();
let longer = (tempData.length <= coughData.length) ? coughData.length :
tempData.length;
for(let i = 0, j = 0; i < longer; ++i, ++j) {
newArray.push(Object.assign(coughData[i], tempData[j]));
}
Вывести на консоль:
[ { day: 'Mon', count: 2, temp: 33.6 },
{ day: 'Tue', count: 1, temp: 34.6 },
{ day: 'Wed', count: 1, temp: 33.1 },
{ day: 'Fri', count: 3, temp: 35.6 },
{ day: 'Sat', count: 1 } ]
const tempData = [
{ day: "Mon", temp: 33.6 },
{ day: "Tue", temp: 34.6 },
{ day: "Wed", temp: 33.1 },
{ day: "Fri", temp: 35.6 }
];
const coughData = [
{ day: "Mon", count: 2 },
{ day: "Wed", count: 1 },
{ day: "Thur", count: 1 },
{ day: "Fri", count: 3 },
{ day: "Sat", count: 1 }
];
const tempRes = [...tempData, ...coughData];
const result = tempRes.reduce((acc, curr) => {
const { day, ...rest } = curr;
acc[day] = acc[day] ? Object.assign({}, acc[day], rest) : curr
return acc;
}, {})
console.info(Object.values(result))
.as-console-wrapper { max-height: 100% !important; top: 0; }
Array.map
преобразует строки массива, его имя — карта, поэтому вам нужно использоватьArray.reduce
.