反转数组

时间:2012-09-05 10:59:23

标签: javascript jquery arrays

我正在使用其原生.filter()方法过滤给定的数组

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

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

创建新数组([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 个答案:

答案 0 :(得分: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];
}

答案 1 :(得分: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]

答案 2 :(得分: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];
}

- 因此您可以传入positivesnegatives,也可以将其保留为未填充状态,在这种情况下,您将获得新的空数组。

答案 3 :(得分:0)

由于安德鲁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);