最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Filter array of objects by common properties - Stack Overflow

programmeradmin6浏览0评论

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: 2}] // becasue this id is the same in all three subarrays

I've only try intersectionBy from loadash but it seems to work in pletely other way :/

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: 2}] // becasue this id is the same in all three subarrays

I've only try intersectionBy from loadash but it seems to work in pletely other way :/

Share Improve this question asked Feb 20, 2020 at 15:00 Piotr WalczakPiotr Walczak 631 gold badge1 silver badge6 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 4

I would take one array (it's enough to take one because if the property is not there its already not mon), 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 mon 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((mon, item)=>{
  if (arr.every(inner => inner.some(_item => _item.id === item.id))) {
    mon.push(item);
  }
  
  return mon;
},[])

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 mon object. 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. If it does not exist create a new object with key id & occurrence. If it exist then increase the value of occurrence. This will give the most mon id, even if an id is not present in few child array

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.

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 mon between those two. intersectionAll wraps this behavior up, folding intersection over an array of arrays.

This breakdown is useful, as intersection is a useful function on its own too. And abstracting out the id check into a function you need to supply means these functions are much more generic.

发布评论

评论列表(0)

  1. 暂无评论