【问题标题】:Combine matching object arrays组合匹配的对象数组
【发布时间】:2018-04-02 04:35:47
【问题描述】:

我正在尝试将项目内的嵌套对象与相同的键结合起来。

  • 查找重复的“顶级”值,
  • 将重复的“顶级”项目合并为一个对象(包括它们的子对象。
  • “类型”数组中不应有重复值

我在这里试过https://jsfiddle.net/Lpq6huvw/410/

输入数据:

[{
    "a": "Mon",
    "type": [{
        "b": 1
    }, {
        "b": 3
    }]
}, {
    "a": "Mon",
    "type": [{
        "b": 2
    }]
}, {
    "a": "Tue",
    "type": [{
        "b": 40
    }]
}, {
    "a": "Tue",
    "type": [{
        "b": 50
    }]
}, {
    "a": "Wed",
    "type": [{
        "b": 30
    }]
}]

进入这个数组:

    [{
      "a": "Mon",
      "type": [{
        "b": 1
      }, {
        "b": 3
      },
      {
        "b": 2
      }]
    }, 
    {
      "a": "Tue",
      "type": [{
        "b": 40
      },
      {
        "b": 50
      }]
    }, {
      "a": "Wed",
      "type": [{
        "b": 30
      }]
    }]

我在下面尝试了这个,它将所有重复的项目映射为一个对象。但是,我希望它在其“顶级”前身下映射每个。

const z = _.uniqBy(_.filter(data.map(e=>e.a), v => _.filter(data.map(e=>e.a), v1 => v1 === v).length > 1))
const dupes = data.filter(itm => z.includes(itm.a))

const flat = _.flatMap(dupes, item => 
                        _(item.type)
                          .map(v => ({b: v.b}))
                          .value()
)

【问题讨论】:

  • 属性名称是否始终相同,只是值发生变化?
  • 是的,它们将保持不变
  • "'type' 数组中不应该有重复的值" - 你的意思是输入永远不会有重复的type 值,或者输入可能有重复但输出不应该?

标签: javascript arrays lodash arr


【解决方案1】:

这是一个没有 lodash 的答案:

function combine (input) {
  const hash = input.reduce((result, current) => {
    if (result[current['a']]) {
      result[current['a']] = result[current['a']].concat(current['type'])
    } else {
      result[current['a']] = current['type']
    }

    return result
  }, {})

  return Object.keys(hash).map(key => {
    return {
      a: key,
      type: hash[key]
    }
  })
}

【讨论】:

    【解决方案2】:

    ES6:您可以使用 Array#reduce 进行迭代,将项目收集到 Map 中,然后使用扩展语法和 Map#values 转换回数组:

    const data = [{"a":"Mon","type":[{"b":1},{"b":3}]},{"a":"Mon","type":[{"b":2}]},{"a":"Tue","type":[{"b":40}]},{"a":"Tue","type":[{"b":50}]},{"a":"Wed","type":[{"b":30}]}];
    
    const result = [...data.reduce((m, { a, type }) => {
      const item = m.get(a) || { a, type: [] }; // use a Set to maintain uniqueness
      
      item.type.push(...type);
      
      return m.set(a, item);
    }, new Map).values()]
    .map(({ a, type }) => ({ // make types unique again
      a, 
      type: [...type.reduce((m, o) => m.has(o.b) ? m : m.set(o.b, o), new Map).values()]
    }));
    
    
    console.log(result);

    Lodash:使用_.groupBy() 获取一组具有相同a 属性的所有对象。映射组,并使用_.mergeWith() 合并每个组,并连接所有type 数组。 使用 map 再次传递以使 type 数组中的所有项目唯一。

    const data = [{"a":"Mon","type":[{"b":1},{"b":3}]},{"a":"Mon","type":[{"b":2}]},{"a":"Tue","type":[{"b":40}]},{"a":"Tue","type":[{"b":50}]},{"a":"Wed","type":[{"b":30}]}];
    
    
    const result = _(data)
      .groupBy('a')
      .map((group) => _.mergeWith({}, ...group, ((objValue, srcValue, key) =>
        key === 'type' ? (objValue || []).concat(srcValue) : undefined
      )))
      .map((obj) => Object.assign(obj, { type: _.uniq(obj.type) }))
      .value();
    
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

    【讨论】:

    • 感谢那些 - 但似乎都没有在 b 属性内显示多个项目。你能查一下吗?
    【解决方案3】:

    我个人觉得 Javascript 的内置函数很好用,而且似乎比一些 lodash 函数更容易理解。

    例如。

    var data = [{"a":"Mon","type":[{"b":1},{"b":3}]},{"a":"Mon","type":[{"b":2},{"b":3}]},{"a":"Tue","type":[{"b":40}]},{"a":"Tue","type":[{"b":50}]},{"a":"Wed","type":[{"b":30}]}];
    
        
    var result = data.reduce((acc, val) => {
      var found = acc.find((findval) => val.a === findval.a);
      if (!found) acc.push(val)
      else found.type = found.type.concat(
        val.type.filter((f) => !found.type.find((findval) => f.b === findval.b)));
      return acc;
    }, []);
     
    console.log(result);

    【讨论】:

    • 极简实现。只是有点困惑为什么数据被命名为var a,然后它返回a。无论哪种方式 - 它都有效!
    • a 在 return 是 reduce 函数中的累加器。我将重命名一些变量以防止混淆。
    • 仅供参考,我将它与另一个问题的解决方案结合起来-stackoverflow.com/questions/46845461
    • @Ycon 我已经更新了变量名,我认为它更容易理解。一开始就应该这样做,我只是懒惰.. :)
    • 啊,它有一个问题,因为它没有使嵌套项在“名称”上具有应有的唯一性。它是怎么做到的?
    猜你喜欢
    • 2018-10-21
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2013-09-16
    相关资源
    最近更新 更多