#javascript #arrays
#javascript #массивы
Вопрос:
У меня есть 2 массива объектов. Первый массив содержит 12 записей с 2 свойствами date и cost (все равны нулю). В другом массиве всего 5 записей с теми же 2 свойствами date и cost (имеет значения).
Как мне обновить массив 1 на основе массива 2, соответствующего дате и обновляющего стоимость?
array1 = [
{
date: '2020-01',
cost: 0
},
{
date: '2020-02',
cost: 0
},
{
date: '2020-03',
cost: 0
},
{
date: '2020-04',
cost: 0
},
{
date: '2020-05',
cost: 0
},
{
date: '2020-06',
cost: 0
},
{
date: '2020-07',
cost: 0
},
{
date: '2020-08',
cost: 0
},
{
date: '2020-09',
cost: 0
},
{
date: '2020-10',
cost: 0
},
{
date: '2020-11',
cost: 0
},
{
date: '2020-12',
cost: 0
}
];
array2 = [
{
date: '2020-01',
cost: 10
},
{
date: '2020-02',
cost: 5
},
{
date: '2020-05',
cost: 20
},
{
date: '2020-06',
cost: 65
},
{
date: '2020-07',
cost: 11
}
];
окончательный массив:
finaArray = [
{
date: '2020-01',
cost: 10
},
{
date: '2020-02',
cost: 5
},
{
date: '2020-03',
cost: 0
},
{
date: '2020-04',
cost: 0
},
{
date: '2020-05',
cost: 20
},
{
date: '2020-06',
cost: 65
},
{
date: '2020-07',
cost: 11
},
{
date: '2020-08',
cost: 0
},
{
date: '2020-09',
cost: 0
},
{
date: '2020-10',
cost: 0
},
{
date: '2020-11',
cost: 0
},
{
date: '2020-12',
cost: 0
}
];
Что я сделал до сих пор:
const test = array1.map((e1, i1) => {
array2.map((e2, i2) => {
if (e1.date === e2.date) {
}
});
});
Комментарии:
1. @blex попытался повторно открыть его и отправить соответствующее изменение, но не позволил мне. Просто хотел отправить его до конца выходных, иначе я бы не вернулся к нему снова до следующих выходных. Но спасибо за вашу помощь
2. Нет проблем, я просто сообщал вам, что если бы вы подождали еще 2 минуты, еще 1 человек проголосовал бы за его повторное открытие, и у вас были бы ответы 😉
3. Спасибо, blex новичок в этом и в том, как это работает. Теперь я знаю, что в следующий раз буду более терпеливым.
Ответ №1:
Мой ответ перебирает каждый экземпляр только один раз в каждом массиве, превращая array2 в объект с датой в качестве ключа, используя Object.assign()
, который затем сравнивается с array1 map()
, просматривая дату.
function turnIntoObj(arr) {
return Object.assign(...arr.map(item => ({ [item.date]: item.cost })));
}
function joinArr(originalArr, toBeAddedArr) {
let toBeAddedObj = turnIntoObj(toBeAddedArr);
return originalArr.map((item) => {
if (toBeAddedObj[item.date]) {
item.cost = toBeAddedObj[item.date];
}
return item;
});
}
array1 = [
{
date: '2020-01',
cost: 0
},
{
date: '2020-02',
cost: 0
},
{
date: '2020-03',
cost: 0
},
{
date: '2020-04',
cost: 0
},
{
date: '2020-05',
cost: 0
},
{
date: '2020-06',
cost: 0
},
{
date: '2020-07',
cost: 0
},
{
date: '2020-08',
cost: 0
},
{
date: '2020-09',
cost: 0
},
{
date: '2020-10',
cost: 0
},
{
date: '2020-11',
cost: 0
},
{
date: '2020-12',
cost: 0
}
];
array2 = [
{
date: '2020-01',
cost: 10
},
{
date: '2020-02',
cost: 5
},
{
date: '2020-05',
cost: 20
},
{
date: '2020-06',
cost: 65
},
{
date: '2020-07',
cost: 11
}
];
let updatedArr = joinArr(array1, array2);
console.log(updatedArr);
Ответ №2:
Вы можете использовать filter
, чтобы получить элементы с одинаковой датой и reduce
рассчитать сумму их затрат:
const array1 = [{date:"2020-01",cost:0},{date:"2020-02",cost:0},{date:"2020-03",cost:0},{date:"2020-04",cost:0},{date:"2020-05",cost:0},{date:"2020-06",cost:0},{date:"2020-07",cost:0},{date:"2020-08",cost:0},{date:"2020-09",cost:0},{date:"2020-10",cost:0},{date:"2020-11",cost:0},{date:"2020-12",cost:0}],
array2 = [{date:"2020-01",cost:10},{date:"2020-02",cost:5},{date:"2020-05",cost:20},{date:"2020-06",cost:65},{date:"2020-07",cost:11}];
const test = array1.map((a) => {
const toMerge = array2.filter(b => a.date === b.date);
return {
...a,
cost: [a].concat(toMerge).reduce((sum, {cost}) => sum cost, 0)
};
});
console.log(test);
Ответ №3:
Ответ Blex работает нормально, ниже приведено другое базовое решение: (проверено)
var finalArray = [];
for (var i = 0; i < array1.length - 1; i ) {
finalArray.push(array1[i]);
for (var j = 0 ; j < array2.length - 1; j ) {
if (array1[i].date == array2[j].date) {
finalArray[i].cost = array2[j].cost array1[i].cost;
break;
}
}
}
console.log(finalArray);
прилагается снимок экрана с окончательными значениями массива
Ответ №4:
для обновления array1 (без создания нового массива)
const array1 = [{date:"2020-01",cost:0},{date:"2020-02",cost:0},{date:"2020-03",cost:0},{date:"2020-04",cost:0},{date:"2020-05",cost:0},{date:"2020-06",cost:0},{date:"2020-07",cost:0},{date:"2020-08",cost:0},{date:"2020-09",cost:0},{date:"2020-10",cost:0},{date:"2020-11",cost:0},{date:"2020-12",cost:0}],
array2 = [{date:"2020-01",cost:10},{date:"2020-02",cost:5},{date:"2020-05",cost:20},{date:"2020-06",cost:65},{date:"2020-07",cost:11}];
array2.forEach(a2=>
{
let a1 = array1.find(x=>x.date===a2.date)
if(a1) a1.cost = a2.cost
})
array1.forEach( (a1,i) => console.log(`array1[${i}] -> ${JSON.stringify(a1)}`))
Если array1 и array2 находятся в одном и том же порядке, и каждый элемент array2 существует в array1 :
const array1 = [{date:"2020-01",cost:0},{date:"2020-02",cost:0},{date:"2020-03",cost:0},{date:"2020-04",cost:0},{date:"2020-05",cost:0},{date:"2020-06",cost:0},{date:"2020-07",cost:0},{date:"2020-08",cost:0},{date:"2020-09",cost:0},{date:"2020-10",cost:0},{date:"2020-11",cost:0},{date:"2020-12",cost:0}],
array2 = [{date:"2020-01",cost:10},{date:"2020-02",cost:5},{date:"2020-05",cost:20},{date:"2020-06",cost:65},{date:"2020-07",cost:11}];
let a2 = array2.shift()
for(a1 of array1)
{
if (a2.date===a1.date)
{
a1.cost = a2.cost
a2 = array2.shift()
}
if (!a2) break // stop loop update
}
// proof...
array1.forEach( (a1,i) => console.log(`${i}-> ${JSON.stringify(a1)}`))
Ответ №5:
Для этого вы можете использовать reduce,
array1 = [
{
date: '2020-01',
cost: 0
},
{
date: '2020-02',
cost: 0
},
{
date: '2020-03',
cost: 0
},
{
date: '2020-04',
cost: 0
},
{
date: '2020-05',
cost: 0
},
{
date: '2020-06',
cost: 0
},
{
date: '2020-07',
cost: 0
},
{
date: '2020-08',
cost: 0
},
{
date: '2020-09',
cost: 0
},
{
date: '2020-10',
cost: 0
},
{
date: '2020-11',
cost: 0
},
{
date: '2020-12',
cost: 0
}
];
array2 = [
{
date: '2020-01',
cost: 10
},
{
date: '2020-02',
cost: 5
},
{
date: '2020-05',
cost: 20
},
{
date: '2020-06',
cost: 65
},
{
date: '2020-07',
cost: 11
}
];
const ret = array1.reduce((acc, curr) => {
const index = array2.findIndex(item => item.date === curr.date);
if(index > -1){
curr.cost = array2[index].cost;
}
acc.push(curr);
return acc;
}, []);
console.log(ret);