Реагировать на значение списка сортировки и стекирования JS - PullRequest
0 голосов
/ 15 января 2019

Предположим,

const listA = [{"key":"apple", "value":100}, {"key":"banana", "value":50}, {"key":"pearl", "value":10}, {"key":"cherry", "value":5}, {"key":"kiwi", "value":3}]
const listB = [{"key":"peach", "value":30}, {"key":"apple", "value":15}, {"key":"kiwi", "value":10}, {"key":"mango", "value":5}]

Как вы можете видеть, в массиве, в котором есть каждая пара объектов с «ключом» и «значением», я хочу собрать значение для того же ключа в новом списке сборки, новый список сборки также должен быть в упорядочить по значению, например что-то вроде этого ->

const listMerged = [{"key":"apple", "value":115}, {"key":"banana", "value":50} , {"key":"peach", "value":30}, {"key":"kiwi", "value":13}, {"key":"pearl", "value":10}, {"key":"cherry", "value":5}, {"key":"mango", "value":5}]

Только что попробовал что-то вроде этого ->

let newArr = listB.forEach((item) => {

  let ifElemPresentInListA = listA.findIndex((elem) => {
    return Object.keys(elem)[0] === Object.keys(item)[0]
  })

  if (ifElemPresentInListA === -1) {
    listA.push(item)
  } else {
    for (let keys in listA[ifElemPresentInListA]) {
      listA[ifElemPresentInListA][keys] += Object.values(item)[0]
    }
  }

})    

Но результат немного испорчен

Было бы очень полезно, если бы кто-нибудь мог предложить лучший пример кода. Спасибо

Ответы [ 3 ]

0 голосов
/ 15 января 2019

Вы можете сжать два массива в объект, чтобы суммировать значения для соответствующих ключей, а затем создать массив из объекта обратно:

const listA = [{"key":"apple", "value":100}, {"key":"banana", "value":50}, {"key":"pearl", "value":10}, {"key":"cherry", "value":5}, {"key":"kiwi", "value":3}];
const listB = [{"key":"peach", "value":30}, {"key":"apple", "value":15}, {"key":"kiwi", "value":10}, {"key":"mango", "value":5}];

let result = [...listA, ...listB].reduce((acc, item) => {
  acc[item.key] = acc[item.key] ? acc[item.key] + item.value : item.value
  return acc;
}, {});

result = Object.entries(result)
  .map(([key, value]) => ({ key, value }))
  .sort((a, b) => b.value - a.value);

console.log(result);
0 голосов
/ 15 января 2019

Вы можете взять карту и собрать все пары ключ / значение, а затем отсортировать новый массив.

const
    listA = [{ key: "apple", value: 100 }, { key: "banana", value: 50 }, { key: "pearl", value: 10 }, { key: "cherry", value: 5 }, { key: "kiwi", value: 3 }],
    listB = [{ key: "peach", value: 30 }, { key: "apple", value: 15 }, { key: "kiwi", value: 10 }, { key: "mango", value: 5 }],
    result = Array
        .from(
            [...listA, ...listB].reduce((m, { key, value }) => m.set(key, (m.get(key) || 0) + value), new Map),
            ([key, value]) => ({ key, value })
        )
        .sort(({ key: a }, { key: b }) => a.localeCompare(b));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 15 января 2019

Вот потенциальное решение, которое объединяет список, сортирует по ключам, а затем перебирает объединенный / отсортированный массив для условного добавления или увеличения в новом списке.

const listA = [{"key":"apple", "value":100}, {"key":"banana", "value":50}, {"key":"pearl", "value":10}, {"key":"cherry", "value":5}, {"key":"kiwi", "value":3}]
const listB = [{"key":"peach", "value":30}, {"key":"apple", "value":15}, {"key":"kiwi", "value":10}, {"key":"mango", "value":5}]

let lists = [];

listA.concat(listB).sort((a, b) => a.key > b.key).forEach(el => {
  if (lists.length > 0 && lists[lists.length - 1].key === el.key) {
    lists[lists.length - 1].value += el.value;
  } else {
    lists.push(el);
  }
});

console.log(lists.sort((a, b) => b.value - a.value));
...