array.select () w javascript

81

Czy javascript ma podobną funkcjonalność jak Ruby?

array.select {|x| x > 3}

Coś jak:

array.select(function(x) { if (x > 3)  return true})
pierrotlefou
źródło

Odpowiedzi:

135

Jest Array.filter():

var numbers = [1, 2, 3, 4, 5];
var filtered = numbers.filter(function(x) { return x > 3; });

// As a JavaScript 1.8 expression closure
filtered = numbers.filter(function(x) x > 3);

Zauważ, że Array.filter()nie jest to standardowy skrypt ECMAScript i nie pojawia się w specyfikacjach ECMAScript starszych niż ES5 (dzięki Yi Jiang i jAndy). W związku z tym może nie być obsługiwany przez inne dialekty ECMAScript, takie jak JScript (w MSIE).

Aktualizacja z listopada 2020 r . : Array.filter jest teraz obsługiwany we wszystkich głównych przeglądarkach.

BoltClock
źródło
6

Underscore.js jest dobrą biblioteką do tego rodzaju operacji - używa wbudowanych procedur, takich jak Array.filter, jeśli są dostępne, lub używa własnych, jeśli nie.

http://documentcloud.github.com/underscore/

Dokumentacja da wyobrażenie o zastosowaniu - składnia lambda javascript nie jest tak zwięzła jak ruby ​​lub inne (na przykład zawsze zapominam dodać wyraźną instrukcję powrotu), a zakres to kolejny łatwy sposób na złapanie się, ale możesz to zrobić większość rzeczy dość łatwo, z wyjątkiem konstrukcji, takich jak leniwe listy składane.

Z dokumentów dla .select () ( .filter () jest aliasem dla tego samego)

Przeszukuje każdą wartość na liście, zwracając tablicę wszystkich wartości, które przeszły test prawdziwości (iterator). Delegaci do natywnej metody filtru, jeśli istnieje.

  var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
  => [2, 4, 6]
Tim
źródło
5

możesz rozszerzyć swój JS za pomocą metody selekcji takiej jak ta

Array.prototype.select = function(closure){
    for(var n = 0; n < this.length; n++) {
        if(closure(this[n])){
            return this[n];
        }
    }

    return null;
};

teraz możesz tego użyć:

var x = [1,2,3,4];

var a = x.select(function(v) {
    return v == 2;
});

console.log(a);

lub dla obiektów w tablicy

var x = [{id: 1, a: true},
    {id: 2, a: true},
    {id: 3, a: true},
    {id: 4, a: true}];

var a = x.select(function(obj) {
    return obj.id = 2;
});

console.log(a);
głupi
źródło
2
Twoja metoda po prostu zwraca pierwszy element, który pasuje do niej, nie zwraca tablicy, tak jak robi to ruby. Jednak z niewielką zmianą: Array.prototype.select = function (test) {var new_array = [] for (var n = 0; n <this.length; n ++) {if (test (this [n])) {new_array.push (this [n]); }} return new_array; };
Rebekah Waterbury
4

Array.filter nie jest zaimplementowany w wielu przeglądarkach, lepiej zdefiniować tę funkcję, jeśli nie istnieje.

Kod źródłowy Array.prototype znajduje się w MDN

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp */)
  {
    "use strict";

    if (this == null)
      throw new TypeError();

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

    var res = [];
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in t)
      {
        var val = t[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, t))
          res.push(val);
      }
    }

    return res;
  };
}

zobacz https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter, aby uzyskać więcej informacji

xinghua
źródło
na kangax.github.io/compat-table/es5/#test-Array.prototype.filter jeśli wybierze się „Przestarzałe platformy”, a następnie rozwinie „Metody tablicowe”, zobaczy, że „array.prototype.filter” nie jest obsługiwany IE8
George Birbilis