按道具值唯一性过滤对象数组

Posted

技术标签:

【中文标题】按道具值唯一性过滤对象数组【英文标题】:Filter array of objects by prop value uniqueness 【发布时间】:2021-09-08 13:54:37 【问题描述】:

给定这个数据结构:

const arr = [
  
    name: "a",
    id: "1",
    vars: [
       
        sub_name: "aa", 
        sub_val: 32 
      , 
       
        sub_name: "aa", 
        sub_val: 343 
      
    ]
  ,
  
    name: "b",
    id: "2",
    vars: [
       
        sub_name: "bb", 
        sub_val: 32333
      , 
       
        sub_name: "bc", 
        sub_val: 34312
      
  
]

我正在尝试通过 sub_name 的唯一性过滤每个 vars 属性以返回此数据结构:

const arr = [
  
    name: "a",
    id: "1",
    vars: [
       
        sub_name: "aa", 
        sub_val: 32 
      
    ]
  ,
  
    name: "b",
    id: "2",
    vars: [
       
        sub_name: "bb", 
        sub_val: 32333
      , 
       
        sub_name: "bc", 
        sub_val: 34312
      
  
]

我在这里的尝试:

removeDuplicates (arr, prop) 
  return arr.filter((obj, i, a) => 
    return a.map(o => o[prop]).indexOf(obj[prop]) === i
  )


this.someArrayOfObjects.map(o => this.removeDuplicates(o.vars, "sub_name"))

返回一个数组数组。

const arr = [
  [
    name: "a",
    id: "1",
    vars: [
       
        sub_name: "aa", 
        sub_val: 32 
      
    ]
  ],
  [
    name: "b",
    id: "2",
    vars: [
       
        sub_name: "bb", 
        sub_val: 32333
      , 
       
        sub_name: "bc", 
        sub_val: 34312
      
  ]
]

我做错了什么?

【问题讨论】:

【参考方案1】:

您错过了传播...o 以返回数组的其余属性。

const arr = [  name: "a", id: "1", vars: [  sub_name: "aa", sub_val: 32, ,  sub_name: "aa", sub_val: 343, , ], ,  name: "b", id: "2", vars: [  sub_name: "bb", sub_val: 32333, ,  sub_name: "bc", sub_val: 34312, , ], , ];

function removeDuplicates(arr, prop) 
  return arr.filter((obj, i, a) => 
    return a.map(o => o[prop]).indexOf(obj[prop]) === i;
  );


const result = arr.map(o => (
  ...o,
  vars: removeDuplicates(o.vars, "sub_name"),
));

console.log(result);

如果你想在一个函数中做到这一点,你可以使用下面的函数。

const arr = [  name: "a", id: "1", vars: [  sub_name: "aa", sub_val: 32, ,  sub_name: "aa", sub_val: 343, , ], ,  name: "b", id: "2", vars: [  sub_name: "bb", sub_val: 32333, ,  sub_name: "bc", sub_val: 34312, , ], , ];


function removeDuplicates2(arr, prop) 
  return arr.map(e => (
    ...e,
    vars: e.vars.filter(
      (el, i, a) => i === a.findIndex(el2 => el[prop] === el2[prop])
    ),
  ));


const output = removeDuplicates2(arr, "sub_name");

console.log(output);

【讨论】:

我发现这对我的目的最清楚,它使用 ES6 扩展运算符来引导(因为我询问了 ES6)。谢谢!【参考方案2】:

我运行了您的代码,但它没有显示相同的输出。然而,我做了这一改变,它的工作原理:

如果您正在修改一个属性 modify 则返回具有修改后属性的对象:

console.log(arr.map(o =>   o.vars = removeDuplicates(o.vars, "sub_name");
                         return o; ));

【讨论】:

【参考方案3】:

当你调用你的 removeDuplicates 函数时试试这个。

const result = arr.map((a) => 
    a.vars = removeDuplicates(a.vars, 'sub_name')
    return a;
)

【讨论】:

以上是关于按道具值唯一性过滤对象数组的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jq 按元素属性值过滤对象数组?

正在渲染对象数组的数组,不断收到“警告:列表中的每个孩子都应该有一个唯一的“关键”道具。”

markdown 使用ramda按嵌套值过滤对象数组

按数组过滤对象数组

如何从 jquery 对象映射中过滤唯一的数据属性值

根据时间戳条件过滤数组中的唯一对象