【问题标题】:Find matching properties in array of objects (angular5)在对象数组中查找匹配的属性(angular5)
【发布时间】:2018-07-20 12:13:14
【问题描述】:

我有一个包含对象的数组。我想知道对象的某些属性是否匹配并将匹配项保存在新数组中。

例子:

[{id: 1, firstname: 'Bob', Lastname: 'Lupo'}, {id: 2, firstname: 'Tessa', Lastname: 'Moon'},
{id: 3, firstname: 'Erik' , Lastname: 'Deurne'}, {id: 4, firstname: 'Bob', Lastname: 'Lupo'}, {id: 5, firstname: 'Bob' , Lastname: 'Lupo'}]

我想知道对象 firstname 和 lastname 的 2 个属性是否与另一个对象中的属性匹配,然后我想将匹配的 id 放入一个新数组中。

所以在这种情况下,它会是 [[1,4,5]]

有人知道这样做的方法吗?

谢谢

【问题讨论】:

  • 你尝试了什么?
  • @GibboK 循环中的循环可以工作,但它不是一种干净的方法

标签: javascript arrays angular object match


【解决方案1】:

试试这个代码

var array = [{id: 1, firstname: 'Bob', Lastname: 'Lupo'}, {id: 2, firstname: 'Tessa', Lastname: 'Moon'},
{id: 3, firstname: 'Erik' , Lastname: 'Deurne'}, {id: 4, firstname: 'Bob', Lastname: 'Lupo'}, {id: 5, firstname: 'Bob' , Lastname: 'Lupo'}]

let duplicates = {}

array.map(item => {
    let key=item.firstname+'_'+item.Lastname
    if( !duplicates[ key ]){
        duplicates[ key ] = []
    }
    duplicates[ key ].push(item.id)
},{})

duplicateNamesIds = []
Object.values( duplicates ).forEach( value => {
    if( value.length > 1 ){
        duplicateNamesIds.push( value )
    }
})
console.log(duplicateNamesIds)

【讨论】:

  • 代码非常简单;y value.length 给出错误,为什么我们需要这个值已经有匹配的 id`s?
【解决方案2】:

var data = [{
        id: 1,
        firstname: 'Bob',
        Lastname: 'Lupo'
    }, {
        id: 2,
        firstname: 'Tessa',
        Lastname: 'Moon'
    },
    {
        id: 3,
        firstname: 'Erik',
        Lastname: 'Deurne'
    }, {
        id: 4,
        firstname: 'Bob',
        Lastname: 'Lupo'
    }, {
        id: 5,
        firstname: 'Bob',
        Lastname: 'Lupo'
    }
];

var result = data.reduce((obj, val) => {
    obj[val.firstname + "_" + val.Lastname] = obj[val.firstname + "_" + val.Lastname] || [];
    obj[val.firstname + "_" + val.Lastname].push(val.id);
    return obj;
}, {});

result = Object.values(result).filter(val=>val.length>1);

console.log(result);

【讨论】:

  • 然而,这断言firstnameLastname 都不包含_。你永远不知道¯\_(ツ)_/¯
【解决方案3】:

第 1 步是创建一个包含所有 firstname-lastname 组合及其 ID 的树。我们可以在数据上的单个reduce 中执行此操作。 (注意:如果您可以为您的对象提供一个安全使用的哈希函数,那么您不需要在这棵树中设置 2 个级别)

[ { id, firstname, lastname } ] -> { firstname: { lastname: [ id ] } }

console.log(
  getData().reduce(
    (tree, person) => {
      if (!tree[person.firstname])
        tree[person.firstname] = {};
      if (!tree[person.firstname][person.Lastname]) 
        tree[person.firstname][person.Lastname] = [];


      tree[person.firstname][person.Lastname].push(person.id);
      return tree;
    }, {}
  )
);


function getData() { return [{id: 1, firstname: 'Bob', Lastname: 'Lupo'}, {id: 2, firstname: 'Tessa', Lastname: 'Moon'},
{id: 3, firstname: 'Erik' , Lastname: 'Deurne'}, {id: 4, firstname: 'Bob', Lastname: 'Lupo'}, {id: 5, firstname: 'Bob' , Lastname: 'Lupo'}] };

一旦我们有了这棵树,我们就可以进入第 2 步。我们将树展平为仅包含 id 集。然后,我们使用filter过滤掉所有只包含一个id的id集:

{ firstname: { lastname: [ id ] } } -> [ [ id ] ]

const flattenTree = tree => Object.entries(tree)
  .reduce(
    (acc, [k, v]) => Object.entries(v).reduce(
        (acc, [k, v]) => acc.concat([v]),
        acc
      ),
    []
  );
  
const duplicates = xxs => xxs.filter(xs => xs.length > 1);

console.log(
  duplicates(
    flattenTree(getTree())
  )
);



function getTree() {
  return getData().reduce(
    (tree, person) => {
      if (!tree[person.firstname])
        tree[person.firstname] = {};
      if (!tree[person.firstname][person.Lastname]) 
        tree[person.firstname][person.Lastname] = [];


      tree[person.firstname][person.Lastname].push(person.id);
      return tree;
    }, {}
  )
};

function getData() { return [{id: 1, firstname: 'Bob', Lastname: 'Lupo'}, {id: 2, firstname: 'Tessa', Lastname: 'Moon'},
{id: 3, firstname: 'Erik' , Lastname: 'Deurne'}, {id: 4, firstname: 'Bob', Lastname: 'Lupo'}, {id: 5, firstname: 'Bob' , Lastname: 'Lupo'}] };

【讨论】:

    【解决方案4】:

    这个怎么样:

    const data = [
      {id: 1, firstname: 'Bob', Lastname: 'Lupo'}, 
      {id: 2, firstname: 'Tessa', Lastname: 'Moon'},
      {id: 3, firstname: 'Erik' , Lastname: 'Deurne'}, 
      {id: 4, firstname: 'Bob', Lastname: 'Lupo'}, 
      {id: 5, firstname: 'Bob' , Lastname: 'Lupo'}
    ]
    
    // Definitely not the most beautiful code I've ever written
    let result = Object.values(
      data.reduce((a, c) => {
        a[c.firstname] = a[c.firstname] || {};
        a[c.firstname][c.Lastname] = [...(a[c.firstname][c.Lastname] || []), c.id];
        return a;
      }, []))
      .map(o => [].concat(...Object.values(o)))
      .filter(arr => arr.length > 1); 
    
    console.log(result);

    【讨论】:

      猜你喜欢
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 2015-01-20
      • 2013-09-16
      • 2014-02-21
      • 2021-12-22
      • 2021-09-07
      • 2019-05-20
      相关资源
      最近更新 更多