Reputation: 17573
I have 2 arrays like so:
var arrayOne = [
{page:'1',tags:['foo','bar']},
{page:'2',tags:['oh','boy']}
];
var arrayTwo = [
{page:'1',tags:['go','out']},
{page:'9b',tags:['red','blue','green']}
];
I want to compare the two arrays, and if the page
property is the same, replace the tags
property in arrayOne
with the tags
property from arrayTwo
.
So given the example arrays above, only the tags for page: 1
of arrayOne
would get replaced with page: 1
's values from arrayTwo
.
I'm thinking I can do this with underscore.js
, but I'm struggling to see how.
Ideas?
Upvotes: 1
Views: 3436
Reputation: 17573
I was able to do what I needed by using Underscore's _each
by doing one inside of another like so ( http://jsfiddle.net/4JP7g/ ) :
var arrayOne = [
{page:1,tags:["foo","bar"]},
{page:2,tags:["oh","boy"]}
];
var arrayTwo = [
{page:1,tags:["go","out"]},
{page:9,tags:["red","blue","green"]}
];
_.each(arrayOne, function(one){
_.each(arrayTwo, function(two){
if(one.page === two.page){
one.tags = two.tags;
console.log (one.tags);
}
});
});
Upvotes: 0
Reputation: 434665
If you actually have two arrays of JavaScript objects like this:
var a1 = [
{page: '1', tags: ['foo', 'bar']},
{page: '2', tags: ['oh', 'boy']},
//...
];
var a2 = [
{page: '1', tags: ['go', 'out']},
{page: '9b', tags: ['red', 'blue', 'green']},
//...
];
Then I'd convert a2
to a page-to-tags lookup table:
var lookup = { }, i, e;
for(i = 0, e = a2[i]; i < a2.length; e = a2[++i])
lookup[e.page] = e.tags;
and then spin through a1
merging in lookup
values as you go:
for(i = 0, e = a1[i]; i < a1.length; e = a1[++i])
e.tags = lookup[e.page] || e.tags;
Demo: http://jsfiddle.net/ambiguous/aDgH7/
If you must use Underscore, you could replace the loops with _.reduce
and _.each
:
var lookup = _(a2).reduce(function(lookup, e) {
lookup[e.page] = e.tags;
return lookup;
}, { });
_(a1).each(function(e) {
e.tags = lookup[e.page] || e.tags;
});
Demo: http://jsfiddle.net/ambiguous/rkMZz/
If you could assume a modernish JavaScript, then the standard reduce
and forEach
array methods could be used:
var lookup = a2.reduce(function(lookup, e) {
lookup[e.page] = e.tags;
return lookup;
}, { });
a1.forEach(function(e) {
e.tags = lookup[e.page] || e.tags;
});
Demo: http://jsfiddle.net/ambiguous/cy2Qy/
If you actually have arrays of JSON strings then you can mix in JSON.parse
and JSON.stringify
calls to unpack and repack the data.
Upvotes: 1
Reputation: 236022
like
var arrayOne = [
'{"page":"1","tags":["foo","bar"]}',
'{"page":"2","tags":["oh","boy"]}'
];
var arrayTwo = [
'{"page":"1","tags":["go","out"]}',
'{"page":"9b","tags":["red","blue","green"]}'
];
var maxLen = Math.max( arrayOne.length, arrayTwo.length ),
objA, objB;
while( maxLen-- ) {
objA = JSON.parse( arrayOne[ maxLen ] );
objB = JSON.parse( arrayTwo[ maxLen ] );
if( objA.page === objB.page ) {
objA.tags = objB.tags
arrayOne[ maxLen ] = JSON.stringify( objA );
}
}
This is pretty much a perfect world example. It becomes a little bit more tricky if Array one and two do not contain the same amount of items.
Upvotes: 0