Devuelve el valor del índice del método de filtro javascript

6 minutos de lectura

avatar de usuario
alsco77

Tengo una matriz de objetos en mi controlador angular.

Quiero devolver el valor del índice del campo dentro de la matriz que tiene una identificación coincidente con mi parámetro.

Solo habrá un objeto en la matriz con una coincidencia fieldId..

$scope.indexOfField = function(fieldId) {
  return $scope.model.fieldData.filter(function(x) {
    if (x.Id === fieldId) return // ???????
  });
}

  • Esta no es una pregunta de angujarjs, sino una general de javascript, por lo que eliminaría el angularjs etiqueta. Pero es una pregunta interesante de todos modos, porque otros lenguajes tienen métodos para manejar esto. Vea mi respuesta a continuación, donde implemento un conÍndice método en Array.

    – Ferrán Maylinch

    3 mayo 2018 a las 20:46


avatar de usuario
Quime hablar

los .findIndex() método devuelve el índice del primer elemento de la matriz que satisface una condición dada por una función. Si la función devuelve false para todos los elementos de la matriz, el resultado es -1.

Ver la documentación aquí.

En mi ejemplo, x es un elemento para cada iteración y uso la función cruzada para mi condición.

const datas = [];
const fieldId = 5;
let index = datas.findIndex( x => x.Id === fieldId );

  • Agregue alguna descripción de lo que se está haciendo en el código.

    – Gourav

    20 de marzo de 2019 a las 11:28

  • ¡Bienvenido a Stack Overflow! Si bien este código puede resolver la pregunta, incluyendo una explicación de cómo y por qué esto resuelve el problema realmente ayudaría a mejorar la calidad de su publicación y probablemente resulte en más votos a favor. Recuerda que estás respondiendo la pregunta para lectores en el futuro, no solo para la persona que pregunta ahora. Edite su respuesta para agregar explicaciones y dar una indicación de las limitaciones y suposiciones que se aplican.

    – doble pitido

    20 de marzo de 2019 a las 12:28

  • Creo que la última línea debería ser: let index = datas.findIndex( x => x === fieldId );

    – Yuri Khristich

    14 oct 2020 a las 18:20

  • Funcionó muy bien, gracias! era lo que necesitaba

    – Jhonnatan Eduardo

    2 de junio de 2021 a las 14:56

avatar de usuario
Rubén Nagoga

No puede devolver el índice del método de filtro.

El método filter() crea una nueva matriz con todos los elementos que pasan la prueba implementada por la función proporcionada.

Puedes usar forEach

$scope.indexOfField = function(fieldId) {
    var i;
    return $scope.model.fieldData.forEach(function(x, index) {
        if (x.Id === fieldId) {
            i = index;
        }
    });
    // use i
}

o incluso mejor usar for ya que no puede detenerse para cada uno cuando haya encontrado su identificación.

$scope.indexOfField = function(fieldId) {
    var fieldData = $scope.model.fieldData, 
        i = 0, ii = $scope.model.fieldData.length;
    for(i; i < ii; i++) if(fieldData[i].Id === fieldId) break;
    // use i
}

  • Esto iterará sobre cada elemento en lugar de detenerse después de encontrar el elemento correcto.

    – Jivings

    20/10/2014 a las 15:00


  • Gracias. hice algunos cambios en el ciclo for y hace lo que quiero

    – alsco77

    20/10/2014 a las 15:07

  • “i” puede no ser el índice deseado en el caso de que se recorra toda la matriz y no se encuentre el objeto buscado

    – elachell

    1 de junio de 2017 a las 11:10


  • aquí hay una solución simple: stackoverflow.com/a/60223559/6775942

    – AR Nasef

    8 ago a las 12:07

avatar de usuario
jivings

Desde el Array.prototype.filter documentación:

La devolución de llamada se invoca con tres argumentos:

  • el valor del elemento
  • el índice del elemento
  • el objeto Array que se está atravesando

Sin embargo, probablemente debería estar usando el some función si solo hay una instancia en su matriz (ya que se detendrá tan pronto como encuentre la primera aparición), y luego busque el índice usando indexOf:

var field = $scope.model.fieldData.filter(function(x) {
    return x.Id === fieldId;
})[0];
var index = $scope.model.fieldData.indexOf(field);

O repita la matriz hasta que encuentre el elemento correcto:

var index;
$scope.model.fieldData.some(function(x, i) {
    if (x.Id === fieldId) return (index = i);
});

avatar de usuario
decano jones

MÉTODO DE ARRAY (ENCONTRAR MÚLTIPLES ÍNDICES)

[10, 7, 13, 15, 230].map((e,i) => e > 13 ? i : undefined).filter(x => x) 
      //returns [3, 4](*** RETURNS multiple indexes ***)
      //FILTER (is simply just REMOVING the UNDEFINED elements (which are FALSY and considered the same as FALSE)

de lo contrario obtendrás…

[10, 7, 13, 15, 230].map((e,i) => e > 13 ? i : undefined)  //returns [undefined, undefined, undefined, 3, 4]

DEVOLVER MÚLTIPLES ÍNDICES (reemplaza el MÉTODO findIndex)

[1, 1, 2, 2, 2, 3, 4, 5].map((e,i) => e === 2 ? i : undefined).filter(x => x) //returns [2, 3, 4]

DEVOLVER VALORES MÚLTIPLES (reemplaza encontrar MÉTODO)

[5, 12, 8, 130, 44].map((e,i) => e > 13 ? e : undefined).filter(x => x) // returns [130, 44]

avatar de usuario
TJ Crowder

El segundo argumento de su devolución de llamada es el índice. No puedo entender qué quiere que haga/devuelva su función, pero si agrega , index después function(xque le dará acceso al índice para esa iteración.

Trabajando desde el nombre de tu función, no creo que quieras filter en absoluto:

$scope.indexOfField = function(fieldId) {
    var result = -1;
    $scope.model.fieldData.some(function(x, index) {
        if (x.Id === fieldId) {
            result = index;
            return true;
        }
    });
    return result;
}

Array#some se detiene a partir de la primera iteración que devuelve un valor real, por lo que dejaremos de buscar la primera vez que encontremos una coincidencia.

  • el resultado es inalcanzable en este ejemplo

    – alsco77

    20/10/2014 a las 14:57

  • @AlexScott: ¿Qué quiere decir con “inalcanzable”? La devolución de llamada es un cierre, y el cierre tiene acceso a la result variable.

    –TJ Crowder

    20/10/2014 a las 15:00

  • @Jivings: No, por eso estoy usando some en el ejemplo, por lo que nos detenemos tan pronto como encontramos una coincidencia.

    –TJ Crowder

    20 de octubre de 2014 a las 15:08

  • @Jivings: No te sigo. los some bit estuvo allí durante algo así como 10 minutos antes de tu comentario. Pero si el comentario ya no es relevante, no se preocupe, simplemente elimínelo.

    –TJ Crowder

    20 oct 2014 a las 15:19

avatar de usuario
JustAnotherDeveloper

No puede devolver directamente el índice, pero puede establecer el parámetro ‘thisArg’ y establecer datos dentro de él. Esto es más limpio que una variable global.

var data = {
    indexes: []
};
var myArray = [1,2,3,4,5,6,7,8,9,10];

myArray.filter(function (element, index) {
    if (element%2 == 0) {
        this.indexes.push(index);
        return true;
    }
}, data);

console.log(data.indexes); // [1, 3, 5, 7, 9]
data.indexes.forEach(function(value) {
    console.log(myArray[value]);
}); // 2, 4, 6, 8, 10

  • el resultado es inalcanzable en este ejemplo

    – alsco77

    20/10/2014 a las 14:57

  • @AlexScott: ¿Qué quiere decir con “inalcanzable”? La devolución de llamada es un cierre, y el cierre tiene acceso a la result variable.

    –TJ Crowder

    20/10/2014 a las 15:00

  • @Jivings: No, por eso estoy usando some en el ejemplo, por lo que nos detenemos tan pronto como encontramos una coincidencia.

    –TJ Crowder

    20 de octubre de 2014 a las 15:08

  • @Jivings: No te sigo. los some bit estuvo allí durante algo así como 10 minutos antes de tu comentario. Pero si el comentario ya no es relevante, no se preocupe, simplemente elimínelo.

    –TJ Crowder

    20 oct 2014 a las 15:19

Definitivamente puedes (ejem, chico que obtuvo una respuesta aceptada)

const polyfillter = (arr,condition) => arr.map( (e,i) => condition ? i : -1).filter(e=>e>=0)    

Pase una matriz y su condición, y obtenga las claves coincidentes.

ejemplo

mynewstuff = polyfillter(myoldcrud, "e.length > 5")

¿Ha sido útil esta solución?