array.select () en javascript

81

¿Javascript tiene una funcionalidad similar a la de Ruby?

array.select {|x| x > 3}

Algo como:

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

Respuestas:

134

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

Tenga en cuenta que Array.filter()no es ECMAScript estándar y no aparece en las especificaciones de ECMAScript anteriores a ES5 (gracias Yi Jiang y jAndy). Como tal, es posible que no sea compatible con otros dialectos de ECMAScript como JScript (en MSIE).

Actualización de noviembre de 2020 : Array.filter ahora es compatible con todos los navegadores principales.

BoltClock
fuente
6

Underscore.js es una buena biblioteca para este tipo de operaciones: usa las rutinas integradas como Array.filter si está disponible, o usa la suya propia si no.

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

Los documentos darán una idea de uso: la sintaxis lambda de javascript no es tan sucinta como ruby ​​u otras (siempre me olvido de agregar una declaración de retorno explícita, por ejemplo) y el alcance es otra forma fácil de quedar atrapado, pero puede hacerlo la mayoría de las cosas con bastante facilidad con la excepción de construcciones como las comprensiones de listas diferidas.

De los documentos para .select () ( .filter () es un alias para el mismo)

Examina cada valor de la lista y devuelve una matriz de todos los valores que pasan una prueba de verdad (iterador). Delegados al método de filtro nativo, si existe.

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

puedes extender tu JS con un método de selección como este

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

    return null;
};

ahora puedes usar esto:

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

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

console.log(a);

o para objetos en una matriz

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);
tonto
fuente
2
Su método simplemente devuelve el primer elemento que coincide, no devuelve una matriz como lo hace ruby. Sin embargo, con un pequeño cambio: Array.prototype.select = function (test) {var new_array = [] for (var n = 0; n <this.length; n ++) {if (test (this [n])) {new_array.push (este [n]); }} return new_array; };
Rebekah Waterbury
4

Array.filter no está implementado en muchos navegadores, es mejor definir esta función si no existe.

El código fuente de Array.prototype se publica en 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;
  };
}

consulte https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter para obtener más detalles

xinghua
fuente
en kangax.github.io/compat-table/es5/#test-Array.prototype.filter si uno selecciona "Plataformas obsoletas" y luego expande "Métodos de matriz", ven que "array.prototype.filter" no es compatible en IE8
George Birbilis