Каков наилучший способ обновить массив с некоторыми обновленными и удаленными результатами, используя lodash? - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть следующий массив:

workedHours = [
  {hours: 3, id: 1234, name: 'John Doe'},
  {hours: 2, id: 5678, name: 'Steve Harris'},
  {hours: 4, id: 1928, name: 'Richard McNeil'},
  {hours: 1, id: 9876, name: 'Kirk Hammet'},
  {hours: 3, id: 5432, name: 'Lucas Moore'},
]

Я просто получаю следующий ответ с некоторыми обновленными часами и некоторыми удаленными часами:

response = {
  updatedHours: [
    {hours: 4, id: 5678, name: 'Steve Harris'},
    {hours: 2, id: 9876, name: 'Kirk Hammet'},
  ],
  deletedHours: [
    {hours: 3, id: 5432, name: 'Lucas Moore'},
  ]
}

Каков наилучший способ обновления часовмассив, удаляя удаленные часы и заменяя обновленные часы элементами в ответе, используя lodash?Таким образом, я могу получить следующий результат с новыми часами после обновления:

workedHours = [
  {hours: 3, id: 1234, name: 'John Doe'},
  {hours: 4, id: 5678, name: 'Steve Harris'},
  {hours: 4, id: 1928, name: 'Richard McNeil'},
  {hours: 2, id: 9876, name: 'Kirk Hammet'},
]

Я могу думать оптимизированным образом ... Можете ли вы, ребята, помочь мне?Большое спасибо!

Ответы [ 3 ]

0 голосов
/ 25 апреля 2018

Вы можете использовать array.filter для удаления удаленных часов и обновленных часов из исходного массива, а затем отодвинуть все обновленные часы с помощью array.concat.

.

var workedHours = [
  {hours: 3, id: 1234, name: 'John Doe'},
  {hours: 2, id: 5678, name: 'Steve Harris'},
  {hours: 4, id: 1928, name: 'Richard McNeil'},
  {hours: 1, id: 9876, name: 'Kirk Hammet'},
  {hours: 3, id: 5432, name: 'Lucas Moore'},
];
var response = {
  updatedHours: [{hours: 4, id: 5678, name: 'Steve Harris'},{hours: 2, id: 9876, name: 'Kirk Hammet'}],
  deletedHours: [{hours: 3, id: 5432, name: 'Lucas Moore'}]
};

workedHours = workedHours.filter(h =>
    !response.deletedHours.find(dh => dh.id === h.id) &&  
    !response.updatedHours.find(uh => uh.id === h.id)
).concat(response.updatedHours);

console.log(workedHours);
0 голосов
/ 25 апреля 2018

Это решение повторяет массив workedHours один раз и сохраняет исходный порядок.

Используйте _.keyBy() для создания словаря (POJO) обновленных элементов и словаря удаленных элементов.

Итерация workedHours с Array.reduce(). Если элемент находится в обновленном словаре, добавьте обновленный элемент в результат. Если элемент отсутствует в удаленном словаре, добавьте его в результат.

const workedHours = [{"hours":3,"id":1234,"name":"John Doe"},{"hours":2,"id":5678,"name":"Steve Harris"},{"hours":4,"id":1928,"name":"Richard McNeil"},{"hours":1,"id":9876,"name":"Kirk Hammet"},{"hours":3,"id":5432,"name":"Lucas Moore"}];
const response = {"updatedHours":[{"hours":4,"id":5678,"name":"Steve Harris"},{"hours":2,"id":9876,"name":"Kirk Hammet"}],"deletedHours":[{"hours":3,"id":5432,"name":"Lucas Moore"}]};

const updatedDict = _.keyBy(response.updatedHours, 'id');
const deletedDict = _.keyBy(response.deletedHours, 'id');

const result = workedHours.reduce((r, o) => {
  if(updatedDict[o.id]) r.push(updatedDict[o.id]);
  else if(!deletedDict[o.id]) r.push(o);
  
  return r;
}, []);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
0 голосов
/ 25 апреля 2018

Вот идея сделать это при n сложности. Я не использовал lodash, но я считаю, что его можно преобразовать в код, эквивалентный lodash.

Идея такова:

  • Преобразовать массив базовых часов в карту с ключом id.
  • Для каждого из удаленных часов удаляйте запись с карты.
  • Для каждого нашего обновления обновите запись на карте.
  • Получить массив значений с карты, используя Object.values().

Рабочий пример:

const hours = [
  {hours: 3, id: 1234, name: 'John Doe'},
  {hours: 2, id: 5678, name: 'Steve Harris'},
  {hours: 4, id: 1928, name: 'Richard McNeil'},
  {hours: 1, id: 9876, name: 'Kirk Hammet'},
  {hours: 3, id: 5432, name: 'Lucas Moore'},
];

const response = {
  updatedHours: [
    {hours: 4, id: 5678, name: 'Steve Harris'},
    {hours: 2, id: 9876, name: 'Kirk Hammet'},
  ],
  deletedHours: [
    {hours: 3, id: 5432, name: 'Lucas Moore'},
  ]
};

const map = hours.reduce((acc, item) => {
  acc[item.id] = item;
  return acc;
}, {});

response.deletedHours.forEach(hour => {
  delete map[hour.id];
});

response.updatedHours.forEach(hour => {
  map[hour.id] = hour;
});

console.log(Object.values(map));
...