【问题标题】:Merge and concat two arrays of objects - JS合并和连接两个对象数组 - JS
【发布时间】:2021-01-20 19:00:23
【问题描述】:

我有两个对象数组,我想根据不同的属性合并它们,如果列表中不存在某些东西,我也想合并它们。

这就是我所拥有的:

const data1 = [{
  name: 'A',
  id: 1
}, {
  name: 'B',
  id: 2
}]

const data2 = [{
  city: 'X',
  rowID: 1
}, {
  city: 'Y',
  rowID: 2
}, {
  city: 'Z',
  rowID: 3
}]

const result = _.map(data1, function(p) {
  return _.merge(
    p,
    _.find(data2, {
      rowID: p.id
    })
  )
})

console.log(result)

//Expected Result
/**[
  {
    "name": "A",
    "id": 1,
    "city": "X",
    "rowID": 1
  },
  {
    "name": "B",
    "id": 2,
    "city": "Y",
    "rowID": 2
  },
  {
    "name": "",
    "id": "",
    "city": 'Z',
    "rowID": 3
  }
]*/
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>

请指教。

【问题讨论】:

    标签: javascript arrays lodash


    【解决方案1】:

    您可以使用Map 收集合并的对象并获取值。

    const
        merge = data => {
            const
                pattern = {},
                map = new Map;
    
            data.forEach(([objects, key]) => {
                Object.keys(objects[0]).forEach(k => pattern[k] = '');
                objects.forEach(o => map.set(o[key], { ...map.get(o[key]), ...o }));
            });
            return Array.from(map.values(), o => ({ ...pattern, ...o }));
        },
        data1 = [{ name: 'A', id: 1 }, { name: 'B', id: 2 }],
        data2 = [{ city: 'X', rowID: 1 }, { city: 'Y', rowID: 2 }, { city: 'Z', rowID: 3 }],
        result = merge([[data1, 'id'], [data2, 'rwoID']]);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 我不想创建一个名为 empty 的新对象,因为键是动态的,并且会根据 API 更改。我打算将其用作可重用函数,在其中传递两个数据及其对应的键以匹配
    • 看最后一个对象的预期结果。
    • @OriDrori,如果我不应该采用默认对象,结果应该如何具有未给定的属性?
    • @a2441918,现在它收集所有属性并将它们作为模式,用已知值替换空字符串。
    【解决方案2】:

    连接数组,按idrowId分组,合并所有对象并将值映射到空字符串,映射组的对象,并将每个组与默认值合并为一个对象(包括默认空@ 987654323@ 和 name)。

    const { concat, groupBy, mapValues, map, merge } = _
    
    const fn = (getId, ...arrs) => {
      const items = concat(...arrs);
      const defaults = mapValues(merge({}, ...items), () => '');
    
      return map(
        groupBy(items, getId),
        group => merge({}, defaults, ...group)
      )
    }
    
    const data1 = [{"name":"A","id":1},{"name":"B","id":2}]
    
    const data2 = [{"city":"X","rowID":1},{"city":"Y","rowID":2},{"city":"Z","rowID":3}]
    
    const result = fn(o => o.id ?? o.rowID, data1, data2)
    
    console.log(result)
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>

    【讨论】:

    • 最后一个对象中的name和id呢?有没有一种方法可以将它们呈现为空字符串,我将这些数据发送到一个表中,它希望这些值存在。我也可以将它们保留为“-”
    • 看到我们将所有内容合并到一个空对象中,您可以轻松添加默认值。
    • 键是动态的,会根据 API 改变。我打算将其用作可重用函数,在其中传递两个数据及其对应的键以进行匹配。谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    • 2021-03-08
    • 2019-02-20
    • 1970-01-01
    • 2020-02-04
    • 2015-01-26
    • 1970-01-01
    相关资源
    最近更新 更多