array.select () in Javascript

81

Hat Javascript ähnliche Funktionen wie Ruby?

array.select {|x| x > 3}

Etwas wie:

array.select(function(x) { if (x > 3)  return true})
pierrotlefou
quelle

Antworten:

134

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

Beachten Sie, dass dies Array.filter()kein Standard-ECMAScript ist und nicht in ECMAScript-Spezifikationen enthalten ist, die älter als ES5 sind (danke Yi Jiang und jAndy). Daher wird es möglicherweise nicht von anderen ECMAScript-Dialekten wie JScript (auf MSIE) unterstützt.

Update November 2020 : Array.filter wird jetzt in allen gängigen Browsern unterstützt.

BoltClock
quelle
6

Underscore.js ist eine gute Bibliothek für diese Art von Operationen - es verwendet die eingebauten Routinen wie Array.filter, falls verfügbar, oder verwendet eine eigene, wenn nicht.

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

Die Dokumente geben eine Vorstellung von der Verwendung - die Javascript-Lambda-Syntax ist bei weitem nicht so prägnant wie Ruby oder andere (ich vergesse immer, zum Beispiel eine explizite return-Anweisung hinzuzufügen), und der Umfang ist ein weiterer einfacher Weg, um aufzufangen, aber Sie können es tun die meisten Dinge ganz einfach, mit Ausnahme von Konstrukten wie faulen Listenverständnissen.

Aus den Dokumenten für .select () ( .filter () ist ein Alias ​​für dasselbe)

Durchsucht jeden Wert in der Liste und gibt ein Array aller Werte zurück, die einen Wahrheitstest (Iterator) bestehen. Delegiert an die native Filtermethode, falls vorhanden.

  var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
  => [2, 4, 6]
Tim
quelle
5

Sie können Ihr JS mit einer solchen Auswahlmethode erweitern

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

    return null;
};

Jetzt können Sie dies verwenden:

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

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

console.log(a);

oder für Objekte in einem Array

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);
dumm
quelle
2
Ihre Methode gibt nur das erste übereinstimmende Element zurück und gibt kein Array wie Ruby zurück. Mit einer kleinen Änderung wird es jedoch: Array.prototype.select = function (test) {var new_array = [] für (var n = 0; n <this.length; n ++) {if (test (this [n])) {new_array.push (this [n]); }} return new_array; };
Rebekah Waterbury
5

Es gibt auch Array.find()in ES6, das das erste übereinstimmende Element zurückgibt, das es findet.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

const myArray = [1, 2, 3]

const myElement = myArray.find((element) => element === 2)

console.log(myElement)
// => 2
Starcat
quelle
4
Dieser gibt gerade das erste gefundene Element zurück
George Birbilis
Das ist nicht dasselbe wie bei Ruby.
sondra.kinsey
4

Array.filter ist in vielen Browsern nicht implementiert. Es ist besser, diese Funktion zu definieren, wenn sie nicht vorhanden ist.

Der Quellcode für Array.prototype wird in MDN veröffentlicht

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

Weitere Informationen finden Sie unter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Xinghua
quelle
Wenn bei kangax.github.io/compat-table/es5/#test-Array.prototype.filter "Veraltete Plattformen" ausgewählt und dann "Array-Methoden" erweitert werden, wird "array.prototype.filter" bei nicht unterstützt IE8
George Birbilis