2012-09-05 73 views
2

我過濾使用其天然.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; 
    }; 
} 

是否有效?還是我可以做得更好?

任何其他(更優雅)的想法如何解決這個問題?

回答

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]; 
} 
+0

這看起來像一個非常優雅的解決方案(雖然我想不必在通過兩個空(或不空)數組更符合'filter')。 – AKX

+0

感謝您的回覆。但我認爲我不能真正使用它。我需要循環遍歷源數組以實際創建負值。所以我最終會再次循環兩次不是嗎? –

+0

@AndreMeinhold您可以更新與再源陣列的負面例子,預期肯定和你的問題? – raina77ow

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] 
+0

我的擔心之一(如上所述)是對其他人的可讀性和便利性。我不認爲這會有很大幫助:) –

+0

爲什麼?一個'陳',一個'if'陳述。所有其他的速度優化,可以刪除。 –

+0

現在看起來更好。當我寫這篇評論的時候,你已經把它全部排成一線了。 –

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,或者讓他們unpassed在這種情況下,你會得到新的空陣列。

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