【问题标题】:compare two arrays of objects and sort based on one array of objects and push when doesn't match比较两个对象数组并根据一个对象数组排序并在不匹配时推送
【发布时间】:2020-04-13 14:33:36
【问题描述】:

我在 javascript 中有两个数组

array1 = [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}]
array2 = [
         [{id: 5, value:'abc'}, {id: 4, value:'xyz'}],
         [{id: 5, value:'abc'}, {id: 2, value:'pqr'}],
         [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}],
         [{id: 2, value:'pqr'}, {id: 5, value:'abc'}]
]

array2 是对象数组的数组, 数组 2 中的所有这些数组首先应按照 array1 序列进行排序,然后如果该特定 id 不存在于该特定索引处,则应推送具有 null 的对象。

output = [
         [{id: 4, value:'xyz'}, {id: null, value:null}, {id: 5, value:'abc'}],
         [{id: null, value:null}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}],
         [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: null, value:null}],
         [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: null, value:null}],
         [{id: null, value:null}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}]
].

这是我的代码

export const mapOrder = (array, order, key) => {
    let arr = [];
    array.sort((a, b) => {
        let A = a[key];
        let B = b[key];
        if (order.indexOf(A) > order.indexOf(B)) {
            return 1;
        }
        return -1;
    });
    if (order.length > 0) {
        for (let i = 0; i < order.length; i++) {
            for (let j = 0; j < array.length; j++) {
                if (order[i] === array[j].UserId) {
                    arr.push(array[j]);
                } else {
                    arr.push({ id: null, value: null})
                }
            }
        }
        array = arr;
    }
    return arr;
};

【问题讨论】:

  • 什么不起作用?
  • @NinaScholz 我已经添加了代码

标签: javascript arrays node.js angular reactjs


【解决方案1】:

您可以从您的 array2 中创建一个 Map,其中 array2 中对象的每个 id 都指向具有特定 id 值的对象数组。然后您可以在array1 上使用.flatMap(),并通过在地图上使用.get() 来获取当前迭代对象的id 的所有对象。如果.get()什么都不返回,你可以提供默认对象(其中id和value是null):

const array1 = [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}];
const array2 = [{id: 5, value:'abc'}, {id: 4, value:'xyz'}];

// group the arrays into a Map
const grouped = array2.reduce((map, obj) => 
  map.set(obj.id, (map.get(obj.id) || []).concat(obj)),
  new Map
);

const res = array1.flatMap(({id}) => grouped.get(id) || ({id: null, value: null}));
console.log(res);

如果array2 中的对象具有唯一的id 值(即:不能存在具有相同想法的对象),您可能能够删除.flatMap() 和需要在Map 中的对象数组。如果是这种情况,您可以简化上述内容:

const array1 = [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}];
const array2 = [{id: 5, value:'abc'}, {id: 4, value:'xyz'}];

const ids = new Map(array2.map((obj) => [obj.id, obj]));
const res = array1.map(({id}) => ids.get(id) || ({id: null, value: null}));
console.log(res);

【讨论】:

    【解决方案2】:

    首先你可以遍历第二个数组并将 ID 保存到一个新的集合中,然后遍历第一个数组,如果集合中存在当前项的 ID,则返回当前对象或返回带有 id 的对象和值为空`

    const array1 = [{id: 4, value:'xyz'}, {id: 2, value:'pqr'}, {id: 5, value:'abc'}]
    const array2 = [{id: 5, value:'abc'}, {id: 4, value:'xyz'}]
    
    function test(arr1, arr2) {
      const set = new Set()
      arr2.forEach(i => set.add(i.id))
      return arr1.map((i) => set.has(i.id) ? i : { id: null, value: null })
    }
    console.log(test(array1,array2))

    【讨论】:

    • 如果使用 arr2Ids 的 Set 而不是数组,可以避免二次复杂度。
    【解决方案3】:

    你可以先在一个对象中收集对象,然后他们映射收集的对象或取一个占位符。

    var array1 = [{ id: 4, value: 'xyz' }, { id: 2, value: 'pqr' }, { id: 5, value: 'abc' }],
        array2 = [{ id: 5, value: 'abc' }, { id: 4, value: 'xyz' }],
        result = array1.map(
            (o => ({ id }) => o[id] || { id: null, value: null })
            (array2.reduce((r, o) => ({ ...r, [o.id]: o }), {}))
        );
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 2018-05-18
      • 2019-01-04
      • 1970-01-01
      • 2022-01-14
      • 2022-01-02
      • 2016-05-07
      相关资源
      最近更新 更多