0

I have two arrays as follows

const arr1 = ['john', 'robot'];

const arr2 = [{name : 'john'}, {name : 'kevin'}, {name : 'james}];

My desired output is to manipulate array arr1 such that if value of arr1 is not present as a name property in arr2 it should get removed from arr1;

So in the above example after the operation, the output should be

console.log(arr1)  // ['john']

as robot is not present in arr2, it gets removed.

Likewise if I have following set of arrays

const names = ['sachin', 'sehwag'];

const players = [{name : 'dhoni'}, {name : 'dravid'}, {name : 'ganguly'} , {name : 'laxman}];

names array should be manipulated to

console.log(names) // []

as both sachin and sehwag is not present in players array

Please help.Thanks in advance.

2
  • What had you tried so far? Commented Aug 19, 2018 at 16:33
  • i tried looping names array with map method and inside the callback of map did a filter on the players array.However got stuck in getting the desired result. Commented Aug 19, 2018 at 16:42

4 Answers 4

3

If you can use es6, a Set is good for this. They only store unique values and are efficient at lookup. They give constant time lookups, which looping through an array doesn't:

const arr1 = ['john', 'robot'];
const arr2 = [{name : 'john'}, {name : 'kevin'}, {name : 'james'}];

// create a set with names
let testSet = arr2.reduce((set, obj) => set.add(obj.name), new Set)

let filtered = arr1.filter(item => testSet.has(item))
console.log(filtered)

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

1 Comment

I am using ES6, hence using Set seems nice.Your solution worked for me.Thanks
2

You can first grab all the names from array of objects arr2, and then filter the arr1 based on names list..

var arr1 = ["john", "robot"];
var arr2 = [{ name: "john" }, { name: "kevin" }, { name: "james" }];
var names = arr2.map(ob => ob.name);
console.log(arr1.filter(name => names.includes(name)));

var arr1 = ["sachin", "sehwag"];
var arr2 = [
  { name: "dhoni" },
  { name: "dravid" },
  { name: "ganguly" },
  { name: "laxman" }
];
var names = arr2.map(ob => ob.name);
console.log(arr1.filter(name => names.includes(name)));

1 Comment

Your answer is clear, concise and informative. Unfortunately, it doesn't work in IE11. *ducks and runs away*
1
       const arr1 = ['john', 'robot'];
       const arr2 = [{name : 'john'}, {name : 'kevin'}, {name : 'james'}];
        var newArray= [];
        for(var i in arr2) {
            var content = arr2[i]['name'];
              if(arr1.indexOf(content) > -1){
                   newArray.push(content);
                }
        }

    console.log(newArray);

Hope it helps you!

Comments

-1

This sounds like a job for [].filter:

function doTheThingYouWantItToDo(a, b) {
    return a.filter(function(elem) {
        for (var i = 0; i < b.length; i+=1) {
            if (b[i].name == elem) {
                return true;
            }
        }
        return false;
    });
}

3 Comments

Nested loops... ouch.
I forgot about [].indexOf, which I should've used instead.
.indexOf is still a loop over the entire array, so the complexity is still O(nm). Using a set however is only O(n+m) which is considerably faster and more efficient.

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.