迭代JS对象数组并返回匹配的对象,并将其从原始数组中删除?

时间:2017-02-23 14:09:48

标签: javascript

我试图找到一种更好的方法来迭代Javascript中的一个对象数组,我还想做两个更多的功能

  1. 从原始数组中删除匹配的元素
  2. 同样归还。
  3. 例如,

      var originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];
    
      var matchedArray = originalArray.filter(function(n, i, arr) {
          return (n.id == 1 || n.id == 2 || n.id == 5) && arr.splice(i, 1)
      });
    

    输出我正在寻找

      

    原始数组为:[{id:3},{id:4}]

         

    匹配数组为:[{id:1},{id:2},{id:5}]

5 个答案:

答案 0 :(得分:2)

这是一个泛型函数partition:给定一个数组和一个谓词(= boolean)函数,它将数组拆分为“falsy”和“truthy”部分:

function partition (ary, predicate) {
    var rs = [[], []];
    ary.forEach(function(x) {
        rs[predicate(x) ? 1 : 0].push(x);
    });
    return rs;
};
   
///

var originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];

var parts = partition(originalArray, function(n) {
   return n.id == 1 || n.id == 2 || n.id == 5
});

console.log(JSON.stringify(parts[0]));
console.log(JSON.stringify(parts[1]))

答案 1 :(得分:2)

如果删除了一个元素,那么在下一次迭代中,实际的元素索引和回调中的索引会有所不同,这会导致意外输出。

使用while循环以相反的顺序迭代并生成新数组并从主数组中删除该值。虽然您可以使用数组并使用Array#includes方法检查数组中存在的值来避免多种情况(对于较旧的浏览器支持,请使用Array#indexOf方法)。

var matchedArray = [],
  i = originalArray.length;

while (i--) {
  if ([1, 2, 5].includes(originalArray[i].id)) 
    matchedArray.push(originalArray.splice(i, 1)[0])
}

var originalArray = [{
  id: 1
}, {
  id: 2
}, {
  id: 3
}, {
  id: 4
}, {
  id: 5
}];

var matchedArray = [],
  i = originalArray.length;

while (i--) {
  if ([1, 2, 5].includes(originalArray[i].id)) 
    matchedArray.push(originalArray.splice(i, 1)[0])
}

console.log(matchedArray);
console.log(originalArray);

更新1:使用Array#reduceRight方法使用相同逻辑的替代方法。

var matchedArray = originalArray.reduceRight(function(arr, o, i, orig) {
  if ([1, 2, 5].includes(o.id))
    arr.push(orig.splice(i, 1)[0])
  return arr;
}, [])

var originalArray = [{
  id: 1
}, {
  id: 2
}, {
  id: 3
}, {
  id: 4
}, {
  id: 5
}];

var matchedArray = originalArray.reduceRight(function(arr, o, i, orig) {
  if ([1, 2, 5].includes(o.id))
    arr.push(orig.splice(i, 1)[0])
  return arr;
}, [])

console.log(matchedArray);
console.log(originalArray);

更新2:虽然您可以使用Array#filter方法执行此操作,但附加变量会保留已删除元素的数量,这有助于计算更新数组上的新索引。

var c = 0;

var matchedArray = originalArray.filter(function(n, i, arr) {
  return [1, 2, 5].includes(n.id) && arr.splice(i - c--, 1)
});

var originalArray = [{
  id: 1
}, {
  id: 2
}, {
  id: 3
}, {
  id: 4
}, {
  id: 5
}];

var c = 0;

var matchedArray = originalArray.filter(function(n, i, arr) {
  return [1, 2, 5].includes(n.id) && arr.splice(i - c--, 1)
});

console.log(matchedArray);
console.log(originalArray);

答案 2 :(得分:0)

可能的解决方案之一。您可以调整ids数组并指定要过滤的ID。



var originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];
var ids = [1,2,5];

var filtered = [];
var notFiltered = [];

filtered = originalArray.filter(v => ids.some(c => c == v.id));
notFiltered = originalArray.filter(v => filtered.every(c => c.id != v.id));

console.log(filtered);
console.log(notFiltered);




答案 3 :(得分:0)

你可以使用Lodash中的_.remove函数来解决这个问题。

let originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];

const matchedArray = _.remove(originalArray, function(n) {
  return (n.id == 1 || n.id == 2 || n.id == 5);
});

console.log(originalArray);
console.log(matchedArray);
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>

答案 4 :(得分:0)

使用underscoreJs例如:

var originalArray = [{id:1},{id:2},{id:3},{id:4},{id:5}];
var matchedArray = _.filter(originalArray,function(n){return (n.id == 1 || n.id == 2 || n.id == 5);});
originalArray = _.difference(originalArray,matchedArray);