0

I have two arrays containing key/value pairs.

{
    "containerOne": [{
        "Id": 1,
            "Title": "TitleOne",
            "Responsibility": "ValueOne"
    }, {
        "Id": 2,
            "Title": "TitleTwo",
            "Responsibility": "ValueTwo"
    }]
}

{
    "containerTwo": [{
        "Id": 1,
            "Title": "TitleOne",
            "Responsibility": null
    }, {
        "Id": 2,
            "Title": "TitleTwo",
            "Responsibility": "null         
                               }
            ]
    }

I'd like to compare both arrays and compare the title of each container. If the titles match, then I'd like to copy the Responsibility value from containerOne to containerTwo. The ID's will not match, so that can be ruled out. Only the titles will be consistent.

What is the most efficient way to do this please?]

Thanks

=====================================================================

EDIT

=====================================================================

Looking at the arrays a little closer, there is a subtle difference in the data being returned:

{
"AMLookupTasksList":
    [
        {
            "Id":1,
            "Title":"Create and Maintain an Onboarding Document",
            "Responsibility":"1. Onboarding|f101ccf1-c7d5-42e7-ba8f-48e88ac90a3d"
        },
        {
            "Id":2,
            "Title":"Execute Onboarding for New Consultants",
            "Responsibility":"1. Onboarding|f101ccf1-c7d5-42e7-ba8f-48e88ac90a3d"
        }
    ]

}

{
"AMTasksList":
    [
        {
            "Id":4,
            "Title":
                {
                    "$M_1":13,"$c_1":"Create and Maintain an Onboarding Document"
                },
            "Responsibility":null
        },
        {
            "Id":17,
            "Title":
                {
                    "$M_1":12,"$c_1":"Execute Onboarding for New Consultants"
                },
            "Responsibility":null
        }
    ]

}

Do I have additional looping to get to the Title value in the second array?

Sconny
  • 25
  • 1
  • 10

3 Answers3

1

First, create a dictionary from containerTwo:

var c2dict = {};
var c2i = containerTwo.innerContainer;
for (var i = 0; i < c2i.length; i++) {
    c2dict[c2i[i].Title] = c2i[i];
}

Now use this to do the copying of propertyies when titles match:

var c1i = containerOne.innerContainer;
for (var i = 0; i < c1i.length; i++) {
    if (c2dict[c1i[i].Title]) {
        c2dict[c1i[i].Title].Property = c1i[i].Property;
    }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Why do you need a dictionary if you already have containerOne and containerTwo data structures? – Shalom Aleichem Sep 19 '13 at 19:54
  • I prefer `for (var i in c1i){...}` – andrew Sep 19 '13 at 19:55
  • @AlexArgutin Because the only way to find a title in the original container is by linear search. – Barmar Sep 19 '13 at 19:55
  • @andrew Technically, if you do that you should check `if (c1i.hasOwnProperty(i))`. – Barmar Sep 19 '13 at 19:57
  • Yes I agree to linear search, but it doesn't mean you need a new data structure for that. – Shalom Aleichem Sep 19 '13 at 19:57
  • @AlexArgutin How would you do it without searching or making a new data structure that's keyed off the title? Your solution is essentially linear search, but it's worse because you keep looping in `containerTwo` even after you've found a match. – Barmar Sep 19 '13 at 20:02
  • What I usually do in practice is create the data structure as a dictionary in the first place, so there's no need to restructure it. – Barmar Sep 19 '13 at 20:03
  • I keep looping because I do not assume that titles are unique. Your solution will not work in this case. – Shalom Aleichem Sep 19 '13 at 20:17
  • @andrew: [Why is using “for…in” with array iteration such a bad idea?](http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-such-a-bad-idea) – Bergi Sep 19 '13 at 20:27
1

This might be a bit of overkill but it ignores the sequence and does a look up in each object. I had to fix some syntax in your objects but I include that: named the objects and took a quote off one of the null values.

var obj1 = {
    "containerOne": [{
        "Id": 1,
            "Title": "TitleOne",
            "Responsibility": "ValueOne"
    }, {
        "Id": 2,
            "Title": "TitleTwo",
            "Responsibility": "ValueTwo"
    }]
};
var obj2 = {
    "containerTwo": [{
        "Id": 1,
            "Title": "TitleOne",
            "Responsibility": null
    }, {
        "Id": 2,
            "Title": "TitleTwo",
            "Responsibility": null
    }]
};

Now the code:

// lookup for first object:
var lookup = {};
// create referece to list above and use it everywhere
lookup.list = obj1;
for (var i = 0, len = lookup.list.containerOne.length; i < len; i++) {
    lookup[lookup.list.containerOne[i].Title] = lookup.list.containerOne[i];
}
// lookup for second object
var otherLookup = {};
otherLookup.list = obj2;
for (var i = 0, len = otherLookup.list.containerTwo.length; i < len; i++) {
    otherLookup[otherLookup.list.containerTwo[i].Title] = otherLookup.list.containerTwo[i];
}

// copy value for Responsibility from first to second on each matched in second.
var i = 0;
var len = lookup.list.containerOne.length;
for (i; i < len; i++) {
    // looks up value from second list in the first one and if found, copies 
    if (lookup[otherLookup.list.containerTwo[i].Title]) {
        otherLookup.list.containerTwo[i].Responsibility = lookup[otherLookup.list.containerTwo[i].Title].Responsibility;
    }
}

// alerts new value using lookup
alert(otherLookup["TitleOne"].Responsibility);

EDIT for new structure, but same answer really:

var obj1 = {
    "AMLookupTasksList": [{
        "Id": 1,
            "Title": "Create and Maintain an Onboarding Document",
            "Responsibility": "1. Onboarding|f101ccf1-c7d5-42e7-ba8f-48e88ac90a3d"
    }, {
        "Id": 2,
            "Title": "Execute Onboarding for New Consultants",
            "Responsibility": "1. Onboarding|f101ccf1-c7d5-42e7-ba8f-48e88ac90a3d"
    }]
};
var obj2 = {
    "AMTasksList": [{
        "Id": 4,
            "Title": {
            "$M_1": 13,
                "$c_1": "Create and Maintain an Onboarding Document"
        },
            "Responsibility": null
    }, {
        "Id": 17,
            "Title": {
            "$M_1": 12,
                "$c_1": "Execute Onboarding for New Consultants"
        },
            "Responsibility": null
    }]
};

var lookup = {};
// create refernece to list above and use it everywhere
lookup.list = obj1;
for (var i = 0, len = lookup.list.AMLookupTasksList.length; i < len; i++) {
    lookup[lookup.list.AMLookupTasksList[i].Title] = lookup.list.AMLookupTasksList[i];
}
var otherLookup = {};
otherLookup.list = obj2;
for (var i = 0, len = otherLookup.list.AMTasksList.length; i < len; i++) {
    otherLookup[otherLookup.list.AMTasksList[i].Title.$c_1] = otherLookup.list.AMTasksList[i];
}

// copy value for Responsibility from first to second
var i = 0;
var len = otherLookup.list.AMTasksList.length;
for (i; i < len; i++) {
    if (lookup[otherLookup.list.AMTasksList[i].Title.$c_1]) {

        otherLookup.list.AMTasksList[i].Responsibility = lookup[otherLookup.list.AMTasksList[i].Title.$c_1].Responsibility;
    }
}

alert(otherLookup["Create and Maintain an Onboarding Document"].Responsibility);

Fiddle for second answer: http://jsfiddle.net/n22V8/

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
  • My answer(s) assume "Title" exists in both cases. "Responsibility" exists in the first object (adds to second if it does not exist) – Mark Schultheiss Sep 19 '13 at 21:26
  • Thanks so much @mark-schultheiss!!! It works great. You are a rock star... Much appreciated. – Sconny Sep 20 '13 at 03:08
0

You should compare properties and set them as the following:

containerOne.innerContainer.forEach(function (element,index) {
    containerTwo.innerContainer.forEach(function (element2,index2) {
       if (element.Title === element2.Title && element.Property != element2.Property) {
           element2.Property = element.Property;
       }
    });
});
Shalom Aleichem
  • 2,987
  • 2
  • 22
  • 34