Как обновить массив в javascript

#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);