Как объединить 2 массива на основе имени ключа и отсортировать на основе объединенного значения? - PullRequest
0 голосов
/ 15 января 2019

предположим, у меня есть два списка

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

Вопрос в том, как объединить два списка в один стек с одним и тем же элементом с увеличением числа и отсортировать по количеству? Я имею в виду окончательный результат должен быть ->

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

Я знаю, что это будет что-то вроде:

sortListDesc(list) {

    return obj.sort(function (l1,l2) {
      return l2< l1 ? -1
           : l2 >l1 ? 1
           : 0
    })
  }

но не знаю точно, как сложить число, чем сортировать по количеству.

Ответы [ 3 ]

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

Вы можете использовать reduce и sort и Object.values следующим образом:

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

let merged = Object.values(listA.concat(listB).reduce((acc, a) => {
  const [k, v] = Object.entries(a)[0];
  (acc[k] = acc[k] || {[k]: 0})[k] += v;
  return acc;
}, {}));

merged.sort((a, b) => Object.values(b)[0] - Object.values(a)[0]);
console.log(merged);

Или,

Используя reduce, создайте объект со всеми фруктами в качестве ключей и индивидуальной суммой в качестве значений. Затем используйте Object.entries, sort и map, например:

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

let merged2 = listA.concat(listB).reduce((acc, a) => {
  const [k, v] = Object.entries(a)[0];
  acc[k] = (acc[k] || 0) + v;
  return acc;
}, {});

const final = Object.entries(merged2)
  .sort(([, v1], [, v2]) => v2 - v1)
  .map(([k, v]) => ({[k]: v}))

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

Я думаю, что у меня код немного чище, чем у brk

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

const both = Object.assign({}, ... listA, ... listB); // concatenate both lists and convert them to an object
const lA = Object.assign({}, ...listA); // convert listA to an object
const lB = Object.assign({}, ...listB);

var result = Object.keys(both).map( (a) => { // mapping sums the values and yields an array
  var sum = {};
  sum [a] =(lA[a] ? lA[a] : 0) + (lB[a] ? lB[a] : 0);
  return sum;
});
// sorting in desc order (hence b - a ) based on values (hence b[Object.keys(b)]) rather than keys
result.sort((a,b) => b[Object.keys(b)] - a[Object.keys(a)] ); 

Сложность связана с тем, что вы храните значения в виде массива. Я считаю, что это не лучший способ получить его, потому что массив может иметь несколько элементов с одинаковыми ключами. Например. вы можете получить что-то вроде этого: const listA = [{"apple":100},...,{"apple":10}], который действителен, но может создать проблему. Я предлагаю вам рассмотреть возможность использования его как объекта, например: const listA = {{'apple': 100}, {'banana':50}} это значительно упростит код и позволит избежать дубликатов

Надеюсь, это поможет!

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

Вы можете перебрать второй список, используя forEach, и проверить, присутствует ли тот же элемент в первом списке, используя findIndex. Если элемент отсутствует (-1), поместите элемент в первый список. Если он присутствует, то с помощью индекса получите этот объект, а затем обновите его значение внутри for..in

const listA = [{
  "apple": 100
}, {
  "banana": 50
}, {
  "pearl": 10
}, {
  "cherry": 5
}, {
  "kiwi": 3
}]
const listB = [{
  "peach": 30
}, {
  "apple": 15
}, {
  "kiwi": 10
}, {
  "mango": 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]
    }
  }

})

console.log(listA)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...