0

Hi guys suppose I have following two objects

var obj1 = {one:232,two:3123,three:3232}
var obj2 = {one:323,three:3444,seven:32}

I am trying write a function that will return the properties that are in both objects, assuming that I will always have two objects as arguments. So for my output it'd be awesome to see ["one","three"].

Here's what I have written

var extend = function(obj){ 
    var x = Object.keys(arguments[0]);
    var y = Object.keys(arguments[1]);
    var inter =[];
    for(var i = 0; i < x.length; i++){
        for(var k = 0; k < y.length;i++){
            if(x[i] === y[k]) {
                inter.push(y[k]);
            }

            }
        }
    return inter;   
}

What I expected this to do was to create an array of the properties of both of the objects and check each pair to see if they are equal. If they are I wanted it to push the common items into a new array. For some reason, this doesn't run because it seems to be running indefinitely.

Can anyone help?

theamateurdataanalyst
  • 2,794
  • 4
  • 38
  • 72

3 Answers3

3

Make it easy on yourself-

Object.keys returns an array, you can use array filter.

var commonproperties= function(o1, o2){
    return Object.keys(o1).filter(function(itm){
        return itm in o2
    });
}

var obj1 = {one:232,two:3123,three:3232},
obj2 = {one:323,three:3444,seven:32};
commonproperties(obj1 ,obj2);

/*  returned value: (Array)
['one','three']
*/
kennebec
  • 102,654
  • 32
  • 106
  • 127
0

Start off with

intersection(Object.keys(o1), Object.keys(o2))

Now you just need to write intersection, or find a library which has it (look at underscore).

The point is that intersection is a general operation on sets or lists. Rather than writing intersection logic which is inextricably tangled up with the notion of objects and their keys, find or write a method which performs that general intersection operation, then simply feed it the two lists of keys. This way you can also more easily add features to the intersection logic--for instance, finding the intersection of more than two arrays.

Still, why bother? Well, one good reason is that this kind of code is less prone to the type of bug you ran into, trying to write a bunch of loops.

If you want to write your own intersection, you could do worse than the filter approach by @kennebec:

function intersection(a1, a2) {
    return a1.filter(function(elt) { return a2.indexOf(elt) !== -1; });
}

Another advantage of factoring out the intersection logic this way is that you can generalize the rules for something being "contained" in an array. We'll pass the criterion function in as a third parameter:

function intersection(a1, a2, contains) {
    return a1.filter(function(elt) { return contains(a2, elt); });
}

For instance I could use this to check for key intersection case-insensitively:

intersection(Object.keys(o1), Object.keys(o2), contains_case_insensitive);

We can add a default for the contains parameter to handle the usual case:

function intersection(a1, a2, contains) {
    contains = contains || function(a, e) { return a.indexOf(e) !== -1; };
    return a1.filter(function(elt) { return contains(a2, elt); });
}

Writing this in ES6 with fat-arrow functions is a bit more compact:

function intersection(a1, a2, contains) {
    contains = contains || (a, e) => a.indexOf(e) !== -1;
    var _contains = elt => contains(a2, elt);
    return a1.filter(_contains);
}
0

I made my own since I don't find the one I need. One line intersection

x={x:1, y:2, z:1};
y={x:3, z:4, r:5};

intersect = Object.keys(x).filter(c => Object.keys(y).indexOf(c) !== -1).reduce((a,b) => {let b1={}; b1[b]=x[b]; return {...a, ...b1}}, {});
console.log(intersect);