Reputation: 8389
I have two arrays like below
var arr = ["x", "y", "z", "a", "b", "c"];
var tgtArr = [{val:"a"}, {val:"b"}]; It does not need to be as lengthy as Array `arr`
This is what I have tried
var dest = new Array(arr.length);
for(var i = 0; i < arr.length; i++){
for(var k = 0; k < tgtArr.length; k++){
dest[i] = dest[i] || [];
if(tgtArr[k].val == arr[i]){
dest[i] = arr[i];
}
}
}
console.log(dest);
My Expected output is (for above tgtArr
value)
[{}, {}, {}, {val:"a"}, {val:"b"}, {}];
if tgtArr
is empty Array
[{},{},{},{},{},{}]
Here is the fiddle. Any alternative for this, it seems not a good way to me as I am iterating through the entire array everytime.
Upvotes: 0
Views: 82
Reputation: 83393
Short:
var result = arr.map(function(x) {
return tgtArr.some(function(o) { return o.val == x; }) ? {val:x} : {};
});
This is more efficient:
var set = {};
tgtArr.forEach(function(obj, i) {
set[obj.val] = true;
});
var result = arr.map(function(x) {
return x in set ? {val:x} : {};
});
Upvotes: 2
Reputation: 147503
This is the same as Paul's answer, but with a loop instead of map. It collects the keys first based on the val property, then creates a new array either with empty objects if the key isn't in tgtArr, or copies a reference to the object from tgtArr if it is:
function newArray(arr, tgtArr) {
var keys = {},
i = tgtArr.length,
j = arr.length,
newArr = [];
// Get keys
while (i--) keys[tgtArr[i].val] = tgtArr[i];
// Make new array
while (j--) newArr[j] = arr[j] in keys? keys[arr[j]] : {};
return newArr;
}
It should be efficient as it only traverses each array once.
Upvotes: 1
Reputation: 171690
var tmp = {};
for (var i = 0; i < tgtArr.length; i++) {
tmp[tgtArr[i].val] = i;
}
var dest = [];
for (var i = 0; i < arr.length; i++) {
var obj= tmp[arr[i]] === undefined ? {} : tgtArr[tmp[arr[i]]];
dest.push(obj);
}
Upvotes: 1
Reputation: 102793
I like using map
rather than loops for this kind of thing (Fiddle):
var result = arr.map(function(x) {
var match = tgtArr.filter(function(y) {
return y.val == x;
});
if (match.length == 1) return match[0];
else return {};
});
This is a possibly inefficient, in that it traverses tgtArr
for every item in arr
, so O(n*m). If needed, you could fix that by pre-processing tgtArr
and converting it to a hash map (Fiddle). This way you've got an O(n+m) algorithm (traverse each array once):
var tgtMap = {};
tgtArr.forEach(function(x) { tgtMap[x.val] = x; })
var result = arr.map(function(x) {
var match = tgtMap[x];
return match || {};
});
Upvotes: 1
Reputation: 708
var dest = new Array(arr.length);
for(var i = 0; i < arr.length; i++){
dest[i] = {}
for(var k = 0; k < tgtArr.length; k++){
if(tgtArr[k].val == arr[i]){
dest[i] = tgtArr[k];
}
}
}
console.log(dest);
Upvotes: 1