0

我有两个数组,如下所示

  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`

这是我尝试过的

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

我的预期输出是(对于上述tgtArr值)

  [{}, {}, {}, {val:"a"}, {val:"b"}, {}];

如果tgtArr为空数组

  [{},{},{},{},{},{}]      

这是小提琴。对此的任何替代方案,这对我来说似乎不是一个好方法,因为我每次都在遍历整个数组。

4

5 回答 5

2

短的:

var result = arr.map(function(x) {
    return tgtArr.some(function(o) { return o.val == x; }) ? {val:x} : {};
});

这更有效:

var set = {};
tgtArr.forEach(function(obj, i) {
    set[obj.val] = true;
});
var result = arr.map(function(x) {
    return x in set ? {val:x} : {};
});
于 2013-11-01T03:42:35.003 回答
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);
于 2013-11-01T03:07:39.907 回答
1

我喜欢map对这种事情使用而不是循环(小提琴):

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

这可能是低效的,因为它遍历tgtArr中的每个项目arr,所以 O(n*m)。如果需要,您可以通过预处理tgtArr并将其转换为哈希映射 ( Fiddle ) 来解决此问题。这样你就有了一个 O(n+m) 算法(遍历每个数组一次):

var tgtMap = {};
tgtArr.forEach(function(x) { tgtMap[x.val] = x; })
var result = arr.map(function(x) {
    var match = tgtMap[x];
    return match || {};
});
于 2013-11-01T03:08:01.493 回答
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

于 2013-11-01T03:19:14.577 回答
1

这与保罗的答案相同,但使用循环而不是map。它首先根据val属性收集键,然后如果键不在 tgtArr 中,则使用空对象创建一个新数组,或者如果在 tgtArr 中则从 tgtArr 复制对对象的引用:

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

它应该是有效的,因为它只遍历每个数组一次。

于 2013-11-01T03:37:28.940 回答