1

I am using react-native where i have to filter out the objects from object array on the basics of id which is provides in another array of object. i have array object as:

var objArr = [
    {name:'a',id:1},
    {name:'ab',id:2},
    {name:'abc',id:3}
];
var keys = [
    {user_id:1},
    {user_id:2}
];
var filterResult = objArr.filter((f) => {
                      !this.keys.includes(f)
                   });

how to remove objects from array where id is equal to user id of keys?

2 Answers 2

1

For pure javascript, this works for your case with filter & reduce, (try run below code snippet)

var objArr = [
    {name:'a',id:1},
    {name:'ab',id:2},
    {name:'abc',id:3}
];
var keys = [
    {user_id:1},
    {user_id:2}
];

var filtered = objArr.filter( (o) => {
    return keys.reduce( (final, k) => {
        return final && !(k.user_id == o.id);
    }, true);
});

console.log(filtered);

To prevent reinventing the wheel, suggest to use existing library for this.

lodash does exactly what you need, with differenceWith.

So it becomes clean and elegant:

const filtered = _.differenceWith(objArr, keys, (a, b) => a.id == b.user_id);

Try run code snippet below.

var objArr = [
    {name:'a',id:1},
    {name:'ab',id:2},
    {name:'abc',id:3}
];
var keys = [
    {user_id:1},
    {user_id:2}
];

const filtered = _.differenceWith(objArr, keys, (a, b) => a.id == b.user_id);

console.log(filtered);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Use lodash for react-native:

npm i lodash

and

import _ from 'lodash';

Update 2:

If you're doing performance critical code, that's a totally different story. you have to tune your code by making index, avoid all handy functions like filter, reduce, use traditional for-loop instead.

I made a quick one, it's about 50 times faster than lodash (300 ms to 6 ms), on 100k of objects with 3k of keys:

var filtered = [];
var indexes = {};
for (var i=0; i<keys.length; ++i) {
    indexes[keys[i].user_id] = true;
}
for (var i=0; i<objArr.length; ++i) {
    !indexes[objArr[i].id] && filtered.push(objArr[i]);
}

/* create objects */
function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4();
}

function makeRand() {
  return Math.floor(Math.random() * 5000);
}

var objArr = [];
for (var i=0; i<100000; ++i) {
    objArr.push({
        name: guid(),
        id: makeRand()
    });
}

var keys = [];
for (var i=0; i<3000; ++i) {
    keys.push({
        user_id: makeRand()
    });
}

/* execute method 1 */
console.time('measure method 1');
var filtered = objArr.filter( (o) => {
    return keys.reduce( (final, k) => {
        return final && !(k.user_id == o.id);
    }, true);
});
console.timeEnd('measure method 1');
console.log('measure method 1 totally', filtered.length, ' objects');

/* execute method 2 */
console.time('measure method 2');
var filtered = _.differenceWith(objArr, keys, (a, b) => a.id == b.user_id);
console.timeEnd('measure method 2');
console.log('measure method 2 totally', filtered.length, ' objects');

/* execute method 3 */
console.time('measure method 3');
var filtered = [];
var indexes = {};
for (var i=0; i<keys.length; ++i) {
    indexes[keys[i].user_id] = true;
}
for (var i=0; i<objArr.length; ++i) {
    !indexes[objArr[i].id] && filtered.push(objArr[i]);
}
console.timeEnd('measure method 3');
console.log('measure method 3 totally', filtered.length, ' objects');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Sign up to request clarification or add additional context in comments.

2 Comments

well lodash difference work for me but it taking a lot time...any faster method you can sugggest
See update 2, I made code snippet for all 3 methods. The third one is fastest.
0

One way you could do this is to reduce your keys objects to an array of numbers. The idea is to compare each element.id in your objArr to the ids in your keys array. This seems like what you're trying to do above.

1) Reduce keys:

var reducedKeys = keys.reduce((total, each) => {
   total.push(each.user_id);
   return total;
}, []);

2) Filter out ids not included in keys:

var filterResult = objArr.filter((each) => {
   if (!reducedKeys.includes(each.id)) {
       return each;
   }
});

If you:

console.log(filterResult)

the result is:

[ { name: 'abc', id: 3 } ]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.