Me pregunto si hay una forma conocida, integrada / elegante de encontrar el primer elemento de una matriz JS que coincida con una condición dada. AC # equivalente sería List.Find .
Hasta ahora he estado usando un combo de dos funciones como este:
// Returns the first element of an array that satisfies given predicate
Array.prototype.findFirst = function (predicateCallback) {
if (typeof predicateCallback !== 'function') {
return undefined;
}
for (var i = 0; i < arr.length; i++) {
if (i in this && predicateCallback(this[i])) return this[i];
}
return undefined;
};
// Check if element is not undefined && not null
isNotNullNorUndefined = function (o) {
return (typeof (o) !== 'undefined' && o !== null);
};
Y luego puedo usar:
var result = someArray.findFirst(isNotNullNorUndefined);
Pero dado que hay tantos métodos de matriz de estilo funcional en ECMAScript , ¿tal vez ya exista algo como esto? Me imagino que mucha gente tiene que implementar cosas como esta todo el tiempo ...
javascript
arrays
Jakub P.
fuente
fuente
return (typeof (o) !== 'undefined' && o !== null);
hasta estoreturn o != null;
. Son exactamente equivalentes.Respuestas:
Desde ES6 existe el
find
método nativo para matrices; esto deja de enumerar la matriz una vez que encuentra la primera coincidencia y devuelve el valor.Vieja respuesta:
Tengo que publicar una respuesta para detener estas
filter
sugerencias :-)Puede usar el
some
método Array para iterar la matriz hasta que se cumpla una condición (y luego se detenga). Desafortunadamente, solo devolverá si la condición se cumplió una vez, no por qué elemento (o en qué índice) se cumplió. Entonces tenemos que enmendarlo un poco:fuente
some()
Por otro lado, regresa de inmediato, que es mucho más rápido en casi todos los casos que las soluciones de filtrado.A partir de ECMAScript 6, puede usarlo
Array.prototype.find
para esto. Esto se implementa y funciona en Firefox (25.0), Chrome (45.0), Edge (12) y Safari (7.1), pero no en Internet Explorer o en un montón de otras plataformas antiguas o poco comunes .Por ejemplo, la siguiente expresión se evalúa como
106
.Si desea usar esto en este momento pero necesita soporte para IE u otros navegadores no compatibles, puede usar una cuña. Recomiendo el es6-shim . MDN también ofrece una cuña si, por alguna razón, no desea poner todo el es6-shim en su proyecto. Para obtener la máxima compatibilidad, desea el es6-shim, porque a diferencia de la versión MDN, detecta implementaciones nativas con errores
find
y las sobrescribe (vea el comentario que comienza "Solución de errores en Array # find y Array # findIndex" y las líneas que lo siguen inmediatamente) .fuente
find
es mejor quefilter
ya que sefind
detiene inmediatamente cuando encuentra que un elemento coincide con la condición, mientrasfilter
recorre todos los elementos para proporcionar todos los elementos coincidentes.¿Qué pasa con el uso de filtro y obtener el primer índice de la matriz resultante?
fuente
.shift
aquí?shift
es que "parece inteligente" pero en realidad es más confuso. ¿Quién pensaría que llamarshift()
sin argumentos sería lo mismo que tomar el primer elemento? No está claro IMO. El acceso a la matriz es más rápido de todos modos: jsperf.com/array-access-vs-shift.shift()
más[0]
explícitamente declarado como este. A pesar de eso, es una alternativa que puedes elegir usar o no, aunque me quedaría[0]
.Ya debería estar claro que JavaScript no ofrece tal solución de forma nativa; Aquí están los dos derivados más cercanos, los más útiles primero:
Array.prototype.some(fn)
ofrece el comportamiento deseado de detenerse cuando se cumple una condición, pero solo devuelve si un elemento está presente; No es difícil aplicar algunos trucos, como la solución ofrecida por la respuesta de Bergi .Array.prototype.filter(fn)[0]
lo convierte en un gran one-liner pero es el menos eficiente, ya que tira losN - 1
elementos solo para obtener lo que necesita.Los métodos de búsqueda tradicionales en JavaScript se caracterizan por devolver el índice del elemento encontrado en lugar del elemento mismo o -1. Esto evita tener que elegir un valor de retorno del dominio de todos los tipos posibles; un índice solo puede ser un número y los valores negativos no son válidos.
Ambas soluciones anteriores tampoco admiten la búsqueda offset, por lo que he decidido escribir esto:
fuente
Resumen:
ES6
find()
find()
se encuentra enArray.prototype
modo que se puede usar en cada matriz.find()
toma una devolución de llamada dondeboolean
se prueba una condición. La función devuelve el valor (¡no el índice!)Ejemplo:
fuente
Si está usando
underscore.js
, puede usar sus funcionesfind
yindexOf
funciones para obtener exactamente lo que desea:Documentación:
fuente
A partir de ES 2015,
Array.prototype.find()
proporciona esta funcionalidad exacta.Para los navegadores que no admiten esta función, la Red de desarrolladores de Mozilla ha proporcionado un polyfill (pegado a continuación):
fuente
Array.prototype.find () hace exactamente eso, más información: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
fuente
fuente
Me inspiré en múltiples fuentes en Internet para obtener la solución a continuación. Quería tener en cuenta algunos valores predeterminados y proporcionar una forma de comparar cada entrada para un enfoque genérico que esto resuelve.
Uso: (dando valor "Segundo")
Implementación:
fuente
No hay una función incorporada en Javascript para realizar esta búsqueda.
Si está utilizando jQuery, puede hacer a
jQuery.inArray(element,array)
.fuente
$.inArray
no devuelve un valor booleano, (¡sorprendentemente!) Devuelve el índice del primer elemento coincidente. Sin embargo, todavía no hace lo que el OP solicitó.Una forma menos elegante que tendrá
throw
todos los mensajes de error correctos (basados enArray.prototype.filter
) pero dejará de iterar en el primer resultado esEntonces los ejemplos son
Funciona al terminar
filter
usandothrow
.fuente