简体   繁体   English

按公共属性过滤对象数组

[英]Filter array of objects by common properties

Is it possible in some way to filter let's say such an array of object arrays:是否有可能以某种方式过滤让我们说这样一个对象数组数组:

[[{id: 1}, {id: 2}, {id: 3}], [{id:6}, {id: 2}], [{id: 2}, {id: 1}, {id: 9}, {id: 3}]]

To get array of objects which all arrays have the same property (id), so in this case it output will be:要获取所有数组具有相同属性(id)的对象数组,因此在这种情况下,它的输出将是:

[{id: 2}] // becasue this id is the same in all three subarrays

I've only try intersectionBy from loadash but it seems to work in completely other way :/我只尝试过来自 loadash 的intersectionBy,但它似乎以完全不同的方式工作:/

I would take one array (it's enough to take one because if the property is not there its already not common), in this example I'm taking the first one but probably more efficient will be picking the shortest one.我会取一个数组(取一个就足够了,因为如果属性不存在,它已经不常见了),在这个例子中我取第一个,但可能更有效的是选择最短的一个。

iterate over the array and check for each object if its common to all other arrays.迭代数组并检查每个对象是否与所有其他数组相同。

 const arr = [[{id: 1}, {id: 2}, {id: 3}], [{id:6}, {id: 2}], [{id: 2}, {id: 1}, {id: 9}, {id: 3}]]; let firstArray = arr.shift(); const result = firstArray.reduce((common, item)=>{ if (arr.every(inner => inner.some(_item => _item.id === item.id))) { common.push(item); } return common; },[]) console.log(result);

Using Ramda :使用拉姆达

const input = [[{id: 1}, {id: 2}, {id: 3}], [{id:6}, {id: 2}], [{id: 2}, {id: 1}, {id: 9}, {id: 3}]];
R.intersection(...input);

You can use array reduce , forEach , findIndex and sort to get the most common object.您可以使用数组reduceforEachfindIndexsort来获取最常见的对象。 In first inside the reduce callback use forEach to iterate each of the child array and then use findIndex to find if in accumulator array , there exist an object with same id.首先在 reduce 回调中使用forEach迭代每个子数组,然后使用findIndex查找 accumulator array 中是否存在具有相同 id 的对象。 If it does not exist create a new object with key id & occurrence .如果它不存在,则创建一个具有键id & occurrence的新对象。 If it exist then increase the value of occurrence.如果存在,则增加出现的值。 This will give the most common id , even if an id is not present in few child array这将给出最常见的id ,即使id不存在于少数子数组中

 let data = [ [{id: 1}, {id: 2}, { id: 3}], [{id: 6}, {id: 2}], [{id: 2}, {id: 1}, {id: 9}, { id: 3}] ]; let obj = data.reduce((acc, curr) => { curr.forEach((item) => { let getInd = acc.findIndex((elem) => { return elem.id === item.id }); if (getInd === -1) { acc.push({ id: item.id, occurence: 1 }) } else { acc[getInd].occurence += 1; } }) return acc; }, []).sort((a, b) => { return b.occurence - a.occurence; }); console.log(obj[0])

 var arr = [
   [{id: 1}, {id: 2}, {id: 3}], 
   [{id:6}, {id: 2}], 
   [{id: 2}, {id: 1}, {id: 9}, {id: 3}]
 ]
 var obj = {};
 var arrLength = arr.length;

 arr.forEach((val,index) => {
  val.forEach((item) =>{
    if(index == 0){
        if(!obj.hasOwnProperty(item.id)){
            obj[item.id] = 1;
        }
    }else{
        if(obj.hasOwnProperty(item.id)){
            obj[item.id] = obj[item.id] + 1;
        }else{
           return;
        }
      }
   });
});

var output = [];

for (const property in obj) {
 if(obj[property] == arrLength){
   output.push({
      id: property
   })
 }
}

console.log(output);

My approach is similar to that of naortor, but with an attempt to be more generic.我的方法类似于 naortor 的方法,但试图更通用。

 const intersection = (pred) => (as, bs) => as .filter (a => bs .some (b => pred (a, b))) const intersectionAll = (pred) => (xs) => xs.length ? xs .reduce (intersection (pred)) : [] const input = [[{id: 1}, {id: 2}, {id: 3}], [{id:6}, {id: 2}], [{id: 2}, {id: 1}, {id: 9}, {id: 3}]] const eqIds = (a, b) => a .id == b .id console .log ( intersectionAll (eqIds) (input) )
 .as-console-wrapper {min-height: 100% !important}

This version requires you to say how you identify two equal values.此版本要求您说明如何识别两个相等的值。 (We will check that they have the same id, but any binary predicate function is allowed.) This function is passed to intersection which returns a function that takes two arrays and finds all the element in common between those two. (我们将检查它们是否具有相同的 id,但允许任何二元谓词函数。)这个函数被传递给intersection ,它返回一个函数,该函数接受两个数组并找到这两个数组之间的所有共同元素。 intersectionAll wraps this behavior up, folding intersection over an array of arrays. intersectionAll包装了这个行为,折叠了数组数组的intersection

This breakdown is useful, as intersection is a useful function on its own too.这种细分很有用,因为intersection本身也是一个有用的功能。 And abstracting out the id check into a function you need to supply means these functions are much more generic.将 id 检查抽象为您需要提供的函数意味着这些函数更加通用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM