2

我正在使用其本机方法过滤给定的数组:.filter()

var a = [1,2,3,4,5];

var b = a.filter(function(v) {
    return v > 2;
});

这将创建新的 Array ( [3,4,5])。现在,我还想将过滤后的值放在另一个数组中。我在这里最好的选择是什么?我是不是该

  • 将删除的值推送到同一过滤方法中的新数组中?
  • 编写一个反转函数并在过滤后应用它?

要使用第一个选项,它可能会这样结束:

var b = a.filter(function(v) {
    return v > 2 || !c.push(v);
});

我对这个解决方案的问题是,它有点混合了两种不同的东西,对于将来阅读代码的人来说可能会非常混乱。作为替代方案,我可以调用类似

c = invert(a,b);

function invert(source, compare) {
    return source.filter(filterPositives);

    function filterPositives(v) {
        return compare.indexOf(v) === -1;
    };
}

那有效吗?或者我可以做得更好吗?

任何其他(更优雅)的想法如何解决这个问题?

4

4 回答 4

3

我不认为通过源数组两次是一个优雅的解决方案。但是话又说回来,给自己添加副作用filter也不是很好。

我会通过编写一个filterSplit函数来解决这个问题,比如这个伪代码:

function filterSplit(
      Array source, Array positives, Array negatives, Function filterCb) 
{
  source.forEach(function(el) {
    if (filterCb(el)) {
      positives.push(el); 
    }
    else {
      negatives.push(el);
    }
  }
}

...或者,如果您更喜欢退货中的数组...

function anotherFilterSplit(Array source, Function filterCb) {
  var positives = [], negatives = [];
  // ... the same check and push as above ...
  return [positives, negatives];
}
于 2012-09-05T11:05:20.077 回答
0
var a=[1,2,3,4,5],b=[],c=[];

for(var i=0,l=a.length,ai=a[i];i<l;ai=a[++i])
    if(ai>2)b.push(ai);
    else c.push(ai);

console.log(b,c);
// [3, 4, 5]   [1, 2]
于 2012-09-05T11:12:05.727 回答
0

@raina77ow 的解决方案看起来不错。最重要的是,这是Coco中的一个实现:

function filterSplit (source, predicate, positives = [], negatives = [])
  source.forEach -> (if predicate it then positives else negatives).push el
  return [positives, negatives]

和编译好的 JavaScript

function filterSplit(source, predicate, positives, negatives){
  positives == null && (positives = []);
  negatives == null && (negatives = []);
  source.forEach(function(it){
    return (predicate(it) ? positives : negatives).push(el);
  });
  return [positives, negatives];
}

- 所以你可以传入你的positivesand negatives,或者不通过它们,在这种情况下你会得到新的空数组。

于 2012-09-05T11:13:35.667 回答
0

由于 Andrew D. 已经写了一个很好的答案,我不确定我是否应该写这个,但是:

http://jsfiddle.net/BsJFv/2/

Array.prototype.divide = function(fun, neg) {
    if (this == null) throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun != "function") throw new TypeError();

    if (!(neg instanceof Array)) {
        throw new TypeError();
    }

    var res = [];
    neg.splice(0, neg.length);
    var thisp = arguments[2];
    for (var i = 0; i < len; i++) {
        if (i in t) {
            var val = t[i];
            if (fun.call(thisp, val, i, t)) {
                res.push(val);
            }
            else {
                neg.push(val);
            }
        }
    }

    return res;
};

这样你就得到了一个很好的除法功能。

第一个参数是要除以的函数,第二个参数是负值数组。

唯一的限制是您必须在调用之前将第二个参数实例化为数组:

var negatives = [];
var positives = x.divide(function(elem) {
    /* whatever you want to check */
}, negatives);
于 2012-09-05T11:47:33.070 回答