【问题标题】:remove duplicate elements from an array of objects - es6?从对象数组中删除重复元素 - es6?
【发布时间】:2018-03-29 18:28:05
【问题描述】:

我有以下对象数组。我需要做的只是从所有连接器数组中删除匹配的键值对。

 [  
       {  
          "connector":[  
             {  
                "name":"CC1"
             },
             {  
                "name":"App1"
             },
             {  
                "name":"CC1"
             },
             {  
                "name":"App2"
             },
             {  
                "name":"CC1"
             },
             {  
                "name":"App3"
             }
          ],
          "connections":[  
             {  
                "source":"CC1",
                "target":"App1"
             },
             {  
                "source":"CC1",
                "target":"App2"
             },
             {  
                "source":"CC1",
                "target":"App3"
             }
          ]
       },
       {  
          "connector":[  
             {  
                "name":"CC1"
             },
             {  
                "name":"App1"
             },
             {  
                "name":"CC1"
             },
             {  
                "name":"App2"
             },
             {  
                "name":"CC1"
             },
             {  
                "name":"App3"
             }
          ],
          "connections":[  
             {  
                "source":"CC1",
                "target":"App1"
             },
             {  
                "source":"CC1",
                "target":"App2"
             },
             {  
                "source":"CC1",
                "target":"App3"
             }
          ]
       },
       {  
          "connector":[  
             {  
                "name":"CC1"
             },
             {  
                "name":"App1"
             },
             {  
                "name":"CC1"
             },
             {  
                "name":"App2"
             },
             {  
                "name":"CC1"
             },
             {  
                "name":"App3"
             }
          ],
          "connections":[  
             {  
                "source":"CC1",
                "target":"App1"
             },
             {  
                "source":"CC1",
                "target":"App2"
             },
             {  
                "source":"CC1",
                "target":"App3"
             }
          ]
       },
       {  
          "connector":[  
             {  
                "name":"CC2"
             },
             {  
                "name":"App2"
             }
          ],
          "connections":[  
             {  
                "source":"CC2",
                "target":"App2"
             }
          ]
       }
    ]

我曾尝试在 es6 中使用过滤器、映射和可扩展运算符的组合,但尚未找到实现此目的的最佳组合。 我想要的输出如下:

 [  
           {  
              "connector":[  
                 {  
                    "name":"CC1"
                 },
                 {  
                    "name":"App1"
                 },
                 {  
                    "name":"App2"
                 },
                 {  
                    "name":"App3"
                 }
              ],
              "connections":[  
                 {  
                    "source":"CC1",
                    "target":"App1"
                 },
                 {  
                    "source":"CC1",
                    "target":"App2"
                 },
                 {  
                    "source":"CC1",
                    "target":"App3"
                 }
              ]
           },
           {  
              "connector":[  
                 {  
                    "name":"CC1"
                 },
                 {  
                    "name":"App1"
                 },
                 {  
                    "name":"App2"
                 },
                 {  
                    "name":"App3"
                 }
              ],
              "connections":[  
                 {  
                    "source":"CC1",
                    "target":"App1"
                 },
                 {  
                    "source":"CC1",
                    "target":"App2"
                 },
                 {  
                    "source":"CC1",
                    "target":"App3"
                 }
              ]
           },
           {  
              "connector":[  
                 {  
                    "name":"CC1"
                 },
                 {  
                    "name":"App1"
                 },
                 {  
                    "name":"App2"
                 },
                 {  
                    "name":"App3"
                 }
              ],
              "connections":[  
                 {  
                    "source":"CC1",
                    "target":"App1"
                 },
                 {  
                    "source":"CC1",
                    "target":"App2"
                 },
                 {  
                    "source":"CC1",
                    "target":"App3"
                 }
              ]
           },
           {  
              "connector":[  
                 {  
                    "name":"CC2"
                 },
                 {  
                    "name":"App2"
                 }
              ],
              "connections":[  
                 {  
                    "source":"CC2",
                    "target":"App2"
                 }
              ]
           }
        ]

实现这一目标的最佳解决方案是什么?提前感谢您的帮助..

【问题讨论】:

  • 如果你打算使用 lodash。这就是你可以做到的。 _.map(data, (i) => { i.connector = _.uniqBy(i.connector, 'name'); return i; })
  • 最好、最优化的方法是在冗余数据进入这个对象数组之前停止它。

标签: javascript arrays ecmascript-6 duplicates javascript-objects


【解决方案1】:

setTimeout(doit, 100);

function doit() {
  data.forEach(obj => {
    obj.connector = obj.connector.filter(({name}, i, arr) =>
      arr.findIndex(o => o.name === name) === i
    )
  });

  console.log(data);
}

var data = [{
    "connector": [{
        "name": "CC1"
      },
      {
        "name": "App1"
      },
      {
        "name": "CC1"
      },
      {
        "name": "App2"
      },
      {
        "name": "CC1"
      },
      {
        "name": "App3"
      }
    ],
    "connections": [{
        "source": "CC1",
        "target": "App1"
      },
      {
        "source": "CC1",
        "target": "App2"
      },
      {
        "source": "CC1",
        "target": "App3"
      }
    ]
  },
  {
    "connector": [{
        "name": "CC1"
      },
      {
        "name": "App1"
      },
      {
        "name": "CC1"
      },
      {
        "name": "App2"
      },
      {
        "name": "CC1"
      },
      {
        "name": "App3"
      }
    ],
    "connections": [{
        "source": "CC1",
        "target": "App1"
      },
      {
        "source": "CC1",
        "target": "App2"
      },
      {
        "source": "CC1",
        "target": "App3"
      }
    ]
  },
  {
    "connector": [{
        "name": "CC1"
      },
      {
        "name": "App1"
      },
      {
        "name": "CC1"
      },
      {
        "name": "App2"
      },
      {
        "name": "CC1"
      },
      {
        "name": "App3"
      }
    ],
    "connections": [{
        "source": "CC1",
        "target": "App1"
      },
      {
        "source": "CC1",
        "target": "App2"
      },
      {
        "source": "CC1",
        "target": "App3"
      }
    ]
  },
  {
    "connector": [{
        "name": "CC2"
      },
      {
        "name": "App2"
      }
    ],
    "connections": [{
      "source": "CC2",
      "target": "App2"
    }]
  }
];

【讨论】:

    【解决方案2】:

    如果您只需要地图、过滤器、查找等常用操作,而每个操作都不需要 lodash:

    const data = [{connector:[{name:"CC1"},{name:"App1"},{name:"CC1"},{name:"App2"},{name:"CC1"},{name:"App3"}],connections:[{source:"CC1",target:"App1"},{source:"CC1",target:"App2"},{source:"CC1",target:"App3"}]},{connector:[{name:"CC1"},{name:"App1"},{name:"CC1"},{name:"App2"},{name:"CC1"},{name:"App3"}],connections:[{source:"CC1",target:"App1"},{source:"CC1",target:"App2"},{source:"CC1",target:"App3"}]},{connector:[{name:"CC1"},{name:"App1"},{name:"CC1"},{name:"App2"},{name:"CC1"},{name:"App3"}],connections:[{source:"CC1",target:"App1"},{source:"CC1",target:"App2"},{source:"CC1",target:"App3"}]},{connector:[{name:"CC2"},{name:"App2"}],connections:[{source:"CC2",target:"App2"}]}];
    
    const result = data.map(e => ({ ...e, connector:
      e.connector
        // Filter the original connector array
        // and return only those elements which name is
        // the same as a connection source or target
        .filter(c => e.connections.find(cn => [cn.source, cn.target].indexOf(c.name) !== -1))
            // Remove duplicates by name as @llama notes
        .filter((v, i, ary) => ary.findIndex(c => c.name === v.name) === i)
    }));
    
    console.log(result)

    【讨论】:

    • 您手动从输入 data 中删除了重复项。如果你把它们放回去,你会看到你的.filter() 没有删除它们。
    • 我想你的意思是我的代码不会改变原来的data 变量,对吧?这是有意的。
    • 不,我是说您的示例更改了问题中发布的原始数据,因此要删除的重复项不再存在。将它们放回原处,您会发现您的解决方案不会删除它们。这是因为您的 .find() 回调将为所有重复条目返回 true
    • ...看起来您复制了所需的输出数据而不是实际数据。这就是我的意思:jsfiddle.net/v4p8wsbo 没有删除任何重复的对象。
    【解决方案3】:

    这将过滤掉所有重复的对象,connectorsconnections 对象可以有任意数量的键。

    mapper = (input) => 
          input.map(x => JSON.stringify(x))          // Stringify
          .filter((x, i, a) => a.indexOf(x) === i)   // Filter out repeating elements
          .map(x => JSON.parse(x))                   // Parse stringified object
    
    
    output = input.map(item => 
                ({ 
                   connector: mapper(item.connector), 
                   connections: mapper(item.connections) 
                })
              )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-01
      • 2018-02-26
      • 2020-01-31
      • 2018-08-15
      • 2013-05-20
      • 2011-07-03
      • 2021-06-19
      相关资源
      最近更新 更多