【问题标题】:How to merge 2 arrays based on a key name and sort based on the merged value?如何根据键名合并 2 个数组并根据合并后的值进行排序?
【发布时间】:2019-06-09 04:34:44
【问题描述】:

假设我有两个列表

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
    })
  }

但不知道如何将数字堆叠起来,而不是按数量排序。

【问题讨论】:

标签: javascript reactjs sorting react-native bubble-sort


【解决方案1】:

您可以像这样使用reducesortObject.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.entriessortmap

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

【讨论】:

    【解决方案2】:

    您可以使用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)

    【讨论】:

      【解决方案3】:

      我认为我的代码比 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}} 这将显着简化代码并确保您没有重复

      希望有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-25
        • 2016-11-18
        • 1970-01-01
        • 2013-12-03
        • 2016-11-17
        • 2018-03-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多