filtros ejemplos ejemplo array and javascript

ejemplos - map filter and reduce javascript



Dividiendo una matriz por funciĆ³n de filtro (7)

Tengo una matriz de Javascript que me gustaría dividir en dos en función de si una función llamada en cada elemento devuelve true o false . Esencialmente, este es un array.filter , pero también me gustaría tener a mano los elementos que fueron filtrados.

Actualmente, mi plan es usar array.forEach y llamar a la función de predicado en cada elemento. Dependiendo de si esto es verdadero o falso, empujaré el elemento actual en uno de los dos arreglos nuevos. ¿Hay una forma más elegante o mejor de hacer esto? ¿Un array.filter donde el elemento empujará a otro array antes de que devuelva false , por ejemplo?


Con ES6 puedes hacer uso de la sintaxis de propagación con reduce:

function partition(array, isValid) { return array.reduce(([pass, fail], elem) => { return isValid(elem) ? [[...pass, elem], fail] : [pass, [...fail, elem]]; }, [[], []]); } const [pass, fail] = partition(myArray, (e) => e > 5);

O en una sola línea:

const [pass, fail] = a.reduce(([p, f], e) => (e > 5 ? [[...p, e], f] : [p, [...f, e]]), [[], []]);


En la función de filtro puede empujar sus elementos falsos en otra función externa de variable:

var bad = [], good = [1,2,3,4,5]; good = good.filter(function (value) { if (value === false) { bad.push(value) } else { return true});

Por supuesto, el value === false necesita ser una comparación real;)

Pero hace casi esa misma operación como forEach . Creo que deberías usar forEach para una mejor legibilidad del código.


Esto suena muy similar al método de Enumerable#partition Ruby .

Si la función no puede tener efectos secundarios (es decir, no puede alterar la matriz original), entonces no hay una manera más eficiente de particionar la matriz que iterar sobre cada elemento y empujar el elemento a una de sus dos matrices.

Dicho esto, podría decirse que es más "elegante" crear un método en Array para realizar esta función. En este ejemplo, la función de filtro se ejecuta en el contexto de la matriz original (es decir, this será la matriz original), y recibe el elemento y el índice del elemento como argumentos (similar a each método de jQuery ):

Array.prototype.partition = function (f){ var matched = [], unmatched = [], i = 0, j = this.length; for (; i < j; i++){ (f.call(this, this[i], i) ? matched : unmatched).push(this[i]); } return [matched, unmatched]; }; console.log([1, 2, 3, 4, 5].partition(function (n, i){ return n % 2 == 0; })); //=> [ [ 2, 4 ], [ 1, 3, 5 ] ]


Prueba esto:

function filter(a, fun) { var ret = { good: [], bad: [] }; for (var i = 0; i < a.length; i++) if (fun(a[i]) ret.good.push(a[i]); else ret.bad.push(a[i]); return ret; }

DEMO


Puedes usar lodash.partition

var users = [ { ''user'': ''barney'', ''age'': 36, ''active'': false }, { ''user'': ''fred'', ''age'': 40, ''active'': true }, { ''user'': ''pebbles'', ''age'': 1, ''active'': false } ]; _.partition(users, function(o) { return o.active; }); // → objects for [[''fred''], [''barney'', ''pebbles'']] // The `_.matches` iteratee shorthand. _.partition(users, { ''age'': 1, ''active'': false }); // → objects for [[''pebbles''], [''barney'', ''fred'']] // The `_.matchesProperty` iteratee shorthand. _.partition(users, [''active'', false]); // → objects for [[''barney'', ''pebbles''], [''fred'']] // The `_.property` iteratee shorthand. _.partition(users, ''active''); // → objects for [[''fred''], [''barney'', ''pebbles'']]

o ramda.partition

R.partition(R.contains(''s''), [''sss'', ''ttt'', ''foo'', ''bars'']); // => [ [ ''sss'', ''bars'' ], [ ''ttt'', ''foo'' ] ] R.partition(R.contains(''s''), { a: ''sss'', b: ''ttt'', foo: ''bars'' }); // => [ { a: ''sss'', foo: ''bars'' }, { b: ''ttt'' } ]


Puedes usar reducir para ello:

function partition(array, callback){ return array.reduce(function(result, element, i) { callback(element, i, array) ? result[0].push(element) : result[1].push(element); return result; }, [[],[]] ); };


Se me ocurrió este pequeño chico. Se usa para todos y cada uno de los que describió, pero en mi opinión se ve limpio y conciso.

//Partition function function partition(array, filter) { let pass = [], fail = []; array.forEach((e, idx, arr) => (filter(e, idx, arr) ? pass : fail).push(e)); return [pass, fail]; } //Run it with some dummy data and filter const [lessThan5, greaterThanEqual5] = partition([0,1,4,3,5,7,9,2,4,6,8,9,0,1,2,4,6], e => e < 5); //Output console.log(lessThan5); console.log(greaterThanEqual5);