0

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.

5
  • 1
    should explain what you are trying to acheive....hard to tell from code thhat isn't doing what you want Commented Nov 1, 2013 at 3:00
  • @charlietfl Thanks for helping me to improve the question, I've updated the question. Commented Nov 1, 2013 at 3:03
  • It looks like your fiddle has nothing inside of the target array. Is that the problem? Commented Nov 1, 2013 at 3:07
  • I think you are doing it the other way, maybe if you loop for every tgtArr to find it on arr it will work too, but effectivier Commented Nov 1, 2013 at 3:09
  • @ajax333221 yes, i'd loop through tgtArr to find out the index number of each value in arr, then using that result to construct the final array as well Commented Nov 1, 2013 at 3:12

5 Answers 5

2

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} : {};
});
Sign up to request clarification or add additional context in comments.

2 Comments

Since it's a (more efficient?) version of my answer I have to give it +1. :-)
This will create new objects for all members of the output array, whereas my answer will just create references for those that already exist. Not sure which way the OP wants to go, just figured I'd point that out.
1

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.

Comments

1
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);

2 Comments

dest[i] = {} will replace existing ordered values.
Instead of var dest = new Array(arr.length); consider var dest = [];. It's also a bit inefficient.
1

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 || {};
});

Comments

1
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);     

}

DEMO

Comments

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.