repetidos query objetos objects elementos ejemplo buscar array javascript callback scope

query - ¿Cómo paso un parámetro adicional a la función de devolución de llamada en el método Javascript.filter()?



query array javascript (8)

El segundo parámetro de filtro establecerá esto dentro de la devolución de llamada.

arr.filter(callback[, thisArg])

Entonces podrías hacer algo como:

function startsWith(element) { return element.indexOf(this) === 0; } addressBook.filter(startsWith, wordToCompare);

Quiero comparar cada cadena en una matriz con una cadena dada. Mi implementación actual es:

function startsWith(element) { return element.indexOf(wordToCompare) === 0; } addressBook.filter(startsWith);

Esta simple función funciona, pero solo porque ahora se está configurando wordToCompare como una variable global, pero por supuesto quiero evitar esto y pasarlo como parámetro. Mi problema es que no estoy seguro de cómo se define startsWith (), por lo que acepta un parámetro adicional, porque realmente no entiendo cómo se pasan los parámetros predeterminados. Intenté todas las diferentes formas en que puedo pensar y ninguna de ellas funciona.

Si también pudiera explicar cómo pasaron los parámetros a las funciones de devolución de llamada "integradas" (lo siento, no conozco un término mejor para estas) el trabajo sería genial


Hay una manera fácil de usar la función de filtro, acceder a todos los parámetros y no complicarlo demasiado.

A menos que thisArg de la devolución de llamada esté configurado en otro filtro de ámbito, no crea su propio ámbito, y podemos acceder a los parámetros dentro del alcance actual. Podemos configurar ''esto'' para definir un alcance diferente para acceder a otros valores si es necesario, pero de manera predeterminada se establece en el alcance desde el que se llama. Puede ver que esto se usa para ámbitos angulares en esta pila .

Usar indexOf está derrotando el propósito del filtro y agregando más sobrecarga. El filtro ya está pasando por la matriz, entonces, ¿por qué tenemos que repetirlo nuevamente? En cambio, podemos hacer que sea una simple función pura .

Aquí hay un escenario de caso de uso dentro de un método de clase React donde el estado tiene una matriz llamada ítems , y al usar el filtro podemos verificar el estado existente:

checkList = (item) => { // we can access this param and globals within filter var result = this.state.filter(value => value === item); // returns array of matching items result.length ? return `${item} exists` : this.setState({ items: items.push(item) // bad practice, but to keep it light }); }


Make startsWith acepta la palabra para comparar y devolver una función que luego se utilizará como función de filtro / devolución de llamada:

function startsWith(wordToCompare) { return function(element) { return element.indexOf(wordToCompare) === 0; } } addressBook.filter(startsWith(wordToCompare));

Otra opción sería usar Function.prototype.bind [MDN] (solo disponible en el navegador compatible con ECMAScript 5, seguir un enlace para un shim para navegadores más antiguos) y "arreglar" el primer argumento:

function startsWith(wordToCompare, element) { return element.indexOf(wordToCompare) === 0; } addressBook.filter(startsWith.bind(this, wordToCompare));

Realmente no entiendo cómo se pasan los parámetros predeterminados

No hay nada especial al respecto. En algún momento, filter solo llama a la devolución de llamada y pasa el elemento actual de la matriz. Entonces es una función que llama a otra función, en este caso la devolución de llamada pasa como argumento.

Aquí hay un ejemplo de una función similar:

function filter(array, callback) { var result = []; for(var i = 0, l = array.length; i < l; i++) { if(callback(array[i])) { // here callback is called with the current element result.push(array[i]); } } return result; }


Para aquellos que buscan una alternativa de ES6 utilizando las funciones de flecha, puede hacer lo siguiente.

let startsWith = wordToCompare => (element, index, array) => { return element.indexOf(wordToCompare) === 0; } // where word would be your argument let result = addressBook.filter(startsWith("word"));

La versión actualizada que includes :

const startsWith = wordToCompare => (element, index, array) => { return element.includes(wordToCompare); }


Para cualquiera que se pregunte por qué su función de flechas gordas está ignorando [, thisArg] , por ejemplo, por qué

["DOG", "CAT", "DOG"].filter(animal => animal === this, "DOG") devuelve []

es porque dentro de esas funciones de flecha están vinculadas cuando se crea la función y se establecen en el valor de this en el ámbito abarcador más amplio, por lo que el argumento thisArg se ignora. Lo solucioné bastante fácilmente al declarar una nueva variable en un ámbito principal:

let bestPet = "DOG"; ["DOG", "CAT", "DOG"].filter(animal => animal === bestPet); => ["DOG", "DOG"]

Aquí hay un enlace para leer un poco más: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this


Puede usar la función de flecha dentro de un filtro, como esta:

result = addressBook.filter(element => element.indexOf(wordToCompare) === 0);

Funciones de flecha en MDN

Una expresión de función de flecha tiene una sintaxis más corta en comparación con las expresiones de función y vincula léxicamente este valor (no vincula sus propios argumentos this, arguments, super o new.target). Las funciones de flecha son siempre anónimas. Estas expresiones de función son las más adecuadas para funciones que no son de método y no pueden usarse como constructores.


basado en la respuesta oddRaven y https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Lo hice de 2 maneras diferentes. 1) usando la forma de la función. 2) usando la forma en línea.

//Here is sample codes : var templateList = [ { name: "name1", index: 1, dimension: 1 } , { name: "name2", index: 2, dimension: 1 } , { name: "name3", index: 3, dimension: 2 } ]; //Method 1) using function : function getDimension1(obj) { if (obj.dimension === 1) // This is hardcoded . return true; else return false; } var tl = templateList.filter(getDimension1); // it will return 2 results. 1st and 2nd objects. console.log(tl) ; //Method 2) using inline way var tl3 = templateList.filter(element => element.index === 1 || element.dimension === 2 ); // it will return 1st and 3rd objects console.log(tl3) ;


function startsWith(element, wordToCompare) { return element.indexOf(wordToCompare) === 0; } // ... var word = "SOMETHING"; addressBook.filter(function(element){ return startsWith(element, word); });