首页 文章

下划线/ lodash由多个属性唯一

提问于
浏览
23

我有一个带有重复项的对象数组,我正在尝试获得一个唯一的列表,其中唯一性由对象属性的子集定义 . 例如,

{a:"1",b:"1",c:"2"}

我想在唯一性比较中忽略 c .

我可以做点什么

_.uniq(myArray,function(element) { return element.a + "_" + element+b});

我希望我能做到

_.uniq(myArray,function(element) { return {a:element.a, b:element.b} });

但这不起作用 . 是否有类似我可以做的事情,或者如果我正在比较多个属性,我是否需要创建对象的可比表示?

4 回答

  • 0

    不幸的是,似乎没有一种直接的方法可以做到这一点 . 如果没有为此编写自己的函数,则需要返回可以直接比较相等的内容(如第一个示例中所示) .

    一种方法是只需 .join() 您需要的属性:

    _.uniqBy(myArray, function(elem) { return [elem.a, elem.b].join(); });
    

    或者,您可以使用_.pick_.omit删除任何不需要的内容 . 从那里,你可以使用 _.values.join() ,或甚至只是 JSON.stringify

    _.uniqBy(myArray, function(elem) {
        return JSON.stringify(_.pick(elem, ['a', 'b']));
    });
    

    请记住,就属性顺序而言,对象不是确定性的,因此您可能只想坚持使用显式数组方法 .

    附:将 uniqBy 替换为 uniq for Lodash < 4

  • 28

    我认为join()方法仍然是最简单的 . 尽管在之前的解决方案中引起了关注,但我认为选择正确的分隔符是避免识别出的陷阱的关键(不同的值集返回相同的连接值) . 请记住,分隔符不必是单个字符,它可以是您确信不会在数据本身中自然发生的任何字符串 . 我一直这样做,喜欢用'〜!$〜'作为我的分隔符 . 它还可以包含\ t \ r \ n等特殊字符 .

    如果包含的数据确实是不可预测的,那么最大长度可能是已知的,您可以在加入之前简单地将每个元素填充到其最大长度 .

  • 0

    使用Lodash的uniqWith方法:

    _.uniqWith(array,[comparator])

    此方法与_.uniq类似,只是它接受比较器,该比较器被调用以比较数组的元素 . 结果值的顺序由它们在数组中出现的顺序决定 . 比较器使用两个参数调用:(arrVal,othVal) .

    comparator 返回 true 时,这些项目被视为重复项目,并且只有第一次出现的项目将包含在新数组中 .


    Example:
    我有 latitudelongitude 的位置列表 - 其中一些是相同的 - 我想查看唯一位置列表:

    const locations = [
      {
        name: "Office 1",
        latitude: -30,
        longitude: -30
      },
      {
        name: "Office 2",
        latitude: -30,
        longitude: 10
      },
      {
        name: "Office 3",
        latitude: -30,
        longitude: 10
      }
    ];
    
    const uniqueLocations = _.uniqWith(
      locations,
      (locationA, locationB) =>
        locationA.latitude === locationB.latitude &&
        locationA.longitude === locationB.longitude
    );
    
    // Result has Office 1 and Office 2
    
  • 1

    @voithos和@Danail结合答案提示 . 我如何解决这个问题是在我的数组中的对象上添加一个唯一的键 .

    启动样本数据

    const animalArray = [
      { a: 4, b: 'cat', d: 'generic' },
      { a: 5, b: 'cat', d: 'generic' },
      { a: 4, b: 'dog', d: 'generic' },
      { a: 4, b: 'cat', d: 'generic' },
    ];
    

    在上面的例子中,我希望数组在 ab 中是唯一的,但是现在我有两个具有 a: 4b: 'cat' 的对象 . 通过将b组合成一个字符串,我可以获得一个唯一的密钥来检查 .

    { a: 4, b: 'cat', d: 'generic', id: `${a}-${b}` }. // id is now '4-cat'
    

    Note: 您显然需要映射数据或在创建对象期间执行此操作,因为您无法引用同一对象中对象的属性 .

    现在比较简单......

    _.uniqBy(animalArray, 'id');
    

    生成的数组长度为3,它将删除最后一个副本 .

相关问题