Obtiene el objeto JSON específico por ID de la matriz JSON en AngularJS


95

Tengo un archivo JSON que contiene algunos datos a los que me gustaría acceder en mi sitio web AngularJS. Ahora lo que quiero es obtener solo un objeto de la matriz. Así que d como por ejemplo artículo con id 1.

Los datos se ve así:

{ "results": [ 
    { 
     "id": 1, 
     "name": "Test" 
    }, 
    { 
     "id": 2, 
     "name": "Beispiel" 
    }, 
    { 
     "id": 3, 
     "name": "Sample" 
    } 
] } 

I d como para cargar los datos con AngularJS $ http funcionalidad de esta manera:

$http.get("data/SampleData.json");

que está funcionando. Pero, ¿cómo puedo obtener ahora un objeto de datos específico (por identificación) de la matriz que obtengo de $http.get?

Gracias de antemano por su ayuda.

Saluda Marc

  0

¿Usted ha dado un ir usted mismo? Si es así, ¿podemos ver lo que se te ocurrió? 25 oct. 132013-10-25 12:38:53

+1

Bueno, no tengo idea de qué camino sería el mejor usando AngularJS. Lo que no me gusta es iterar sobre la matriz y hacer un igual en la identificación. Tal vez hay una mejor manera? 25 oct. 132013-10-25 12:40:22

  0

Debe confiar en underscorejs o bibliotecas similares para dicho procesamiento. AngularJS es un framework MVVM y es posible que no tenga una API para esto. 25 oct. 132013-10-25 12:46:52

  0

@marcbaur: debe iterar la matriz. Incluso si usa subrayado, o algo similar, sus funciones, detrás de escena, son solo iterar. 25 oct. 132013-10-25 13:00:06

  0

Agregue el código angular para este 15 jul. 152015-07-15 15:21:26

  0

Parece que es hora de cambiar la respuesta elegida. 23 sep. 152015-09-23 21:01:43

2

La única forma de hacerlo es iterar sobre la matriz. Obviamente, si está seguro de que los resultados están ordenados por ID Usted puede hacer una binary search

+44

... Realmente espero que después de leer esta respuesta la gente no piense que es una buena idea ordenar una matriz y luego hacer una búsqueda binaria. La búsqueda binaria es * inteligente *, seguro, pero * solo * si la matriz ya está ordenada, y en realidad es: 1. fácil de implementar deficientemente, 2. más difícil de leer si está mal implementada. 25 oct. 132013-10-25 14:51:41

+4

Agradecería mucho que los vencedores pudieran motivar su decisión. 13 ene. 152015-01-13 13:02:45

+5

por favor agregue el código angular para este 15 jul. 152015-07-15 15:21:51

  0

Por defecto javascript El tipo de matriz tiene el método find(). El método find() devuelve el valor del primer elemento en la matriz que satisface la función de prueba proporcionada. 20 jul. 172017-07-20 13:12:29


7

Por desgracia (si no me equivoco), creo que es necesario para iterar sobre los resultados objeto.

for(var i = 0; i < results.length; i += 1){ 
    var result = results[i]; 
    if(result.id === id){ 
     return result; 
    } 
} 

Al menos de esta manera se saldrá de la iteración tan pronto como encuentre la id coincidente.

  0

No es una buena práctica usar 'for..in' en arreglos. 25 oct. 132013-10-25 13:11:13

  0

¿Por qué? ¿Tienes algo que respalde eso? 25 oct. 132013-10-25 14:27:23

+9

Bueno, ¿sabes qué ...?Simplemente me fui a volver a leer Javascript, las partes buenas para contrarrestar tu argumento y ¡estoy equivocado! ¡Durante todo este tiempo lo he estado haciendo mal! Aunque no me ha causado ningún problema ... todavía. He actualizado mi respuesta. 25 oct. 132013-10-25 14:34:39


9

Usted puede simplemente bucle sobre la matriz:

var doc = { /* your json */ }; 

function getById(arr, id) { 
    for (var d = 0, len = arr.length; d < len; d += 1) { 
     if (arr[d].id === id) { 
      return arr[d]; 
     } 
    } 
} 

var doc_id_2 = getById(doc.results, 2); 

Si no desea escribir esta bucles desordenados, se puede considerar el uso de underscore.js o Lo-Dash (ejemplo en el segundo):

var doc_id_2 = _.filter(doc.results, {id: 2})[0] 

25

personalmente yo uso destacar para este tipo de cosas ... así

a = _.find(results,function(rw){ return rw.id == 2 }); 

entonces "a" sería la fila que usted quería de su matriz donde la identificación era igual a 2

+1

Me encanta ** guión bajo, pero, ¿es peor tener otra biblioteca JavaScript? _ 26 jul. 142014-07-26 03:09:10

+8

Tenga en cuenta que 'find' puede devolver varios objetos. Como solo queremos uno, podemos usar 'findWhere' que solo devuelve la primera ocurrencia (que sabemos que es la única ocurrencia), p. 'a = _.findWhere (results, {id: 2})'. 18 sep. 142014-09-18 16:47:53


2

Si puede, diseñe su estructura de datos JSON haciendo uso de los índices de la matriz como ID. Incluso puede "normalizar" sus matrices JSON siempre que no tenga problemas haciendo uso de los índices de matriz como "clave principal" y "clave externa", algo así como RDBMS. Como tal, en el futuro, incluso se puede hacer algo como esto:

function getParentById(childID) { 
var parentObject = parentArray[childArray[childID].parentID]; 
return parentObject; 
} 

Ésta es la solución "por diseño". Para su caso, simplemente:

var nameToFind = results[idToQuery - 1].name; 

Por supuesto, si el formato de identificación es algo así como "XX-0001" de la que su índice de la matriz es , entonces usted puede hacer un poco de manipulación de cadenas para asignar La identificación; o de lo contrario no se puede hacer nada al respecto, excepto a través del enfoque de iteración.


12

Puede utilizar ng-repeat y recoger datos sólo si los datos coincide con lo que está buscando usando ng-show por ejemplo:

<div ng-repeat="data in res.results" ng-show="data.id==1"> 
    {{data.name}} 
</div>  
+2

Si su matriz tiene más que un número trivial de elementos, esto creará muchos ámbitos innecesarios que pueden ralentizar su aplicación. 02 sep. 152015-09-02 18:37:36

  0

bajo rendimiento 09 abr. 162016-04-09 01:08:03


221

Utilizando la solución ES6

Para aquellos que todavía leer esta respuesta, si está utilizando ES6 el método find se ha agregado en matrices. Así que asumiendo la misma colección, el solution'd ser:

const foo = { "results": [ 
    { 
     "id": 12, 
     "name": "Test" 
    }, 
    { 
     "id": 2, 
     "name": "Beispiel" 
    }, 
    { 
     "id": 3, 
     "name": "Sample" 
    } 
] }; 
foo.results.find(item => item.id === 2) 

me gustaría ir totalmente para esta solución ahora, ya que es menos complicado su angular o cualquier otro marco. Pure Javascript.

solución angular (solución de edad)

I dirigido a resolver este problema de la siguiente manera:

$filter('filter')(foo.results, {id: 1})[0]; 

Un ejemplo de caso de uso:

app.controller('FooCtrl', ['$filter', function($filter) { 
    var foo = { "results": [ 
     { 
      "id": 12, 
      "name": "Test" 
     }, 
     { 
      "id": 2, 
      "name": "Beispiel" 
     }, 
     { 
      "id": 3, 
      "name": "Sample" 
     } 
    ] }; 

    // We filter the array by id, the result is an array 
    // so we select the element 0 

    single_object = $filter('filter')(foo.results, function (d) {return d.id === 2;})[0]; 

    // If you want to see the result, just check the log 
    console.log(single_object); 
}]); 

Plunker: http://plnkr.co/edit/5E7FYqNNqDuqFBlyDqRh?p=preview

+1

En realidad, ¡creo que sí! Después de obtener la matriz, puede usar la función $ filter para filtrar el elemento con la identificación correcta. 24 jun. 142014-06-24 19:39:18

+10

Esta debería ser la respuesta aceptada. Tenía la misma pregunta en mi cabeza y esta es la única que usa AngularJS existente y no está reinventando la rueda. Y sí, está funcionando. 03 jul. 142014-07-03 14:17:42

+4

+1 por ser esta la respuesta aceptada. La mejor solución usando bibliotecas angulares. 07 oct. 142014-10-07 10:08:14

  0

Un tema relacionado que encontré útil para ejecutar el filtro en una expresión: http://stackoverflow.com/questions/17793751/how-to-filter-by-object-property-in-angularjs 05 jun. 152015-06-05 08:22:03

+1

Plunker con filtro en una expresión: http://plnkr.co/edit/yc0uZejGqWTcUVKvI7Tq?p=preview 05 jun. 152015-06-05 08:28:55

+3

Tenga en cuenta que los filtros encuentran subcadenas insensibles a mayúsculas y minúsculas de forma predeterminada. Así que (foo.results, {id: 2}) devuelve [{id: 12}, {id: 2}], {id: 222}] pero (foo.results, function (d) {return d.id == = 2;}) devuelve [{id: 2}] 26 jul. 152015-07-26 04:31:54

  0

Debería hacer algo como esto: var object_by_id = $ filter ('filter') (foo.results, {id: 2}) [0]; - Ver mi respuesta a continuación. 31 jul. 152015-07-31 19:18:31

  0

cómo es el rendimiento del filtro angular en comparación con las soluciones de subrayado 11 nov. 152015-11-11 10:10:43

  0

¿Qué hay de filtrar con dos 'id's? Quiero decir que el segundo 'id' proviene de datos anidados del 'json'. 06 jun. 162016-06-06 05:41:27

  0

¿cuál es el tiempo de ejecución de esto? 28 mar. 172017-03-28 03:20:03


0
projectDetailsController.controller('ProjectDetailsCtrl', function ($scope, $routeParams, $http) { 
    $http.get('data/projects.json').success(function(data) { 

     $scope.projects = data; 
     console.log(data); 

     for(var i = 0; i < data.length; i++) { 
     $scope.project = data[i]; 
     if($scope.project.name === $routeParams.projectName) { 
      console.log('project-details',$scope.project); 
     return $scope.project; 
     } 
     } 

    }); 
}); 

No estoy seguro si es realmente bueno, pero esto fue útil para mí ... Necesitaba usar $ scope para que funcione correctamente.


16

Solo quiero agregar algo al Willemoes answer. El mismo código escrito directamente en el HTML se verá así:

{{(FooController.results | filter : {id: 1})[0].name }} 

Suponiendo que "los resultados" es una variable de la FooController y que desea mostrar la propiedad "name" del elemento filtrada.

  0

@ Ena-¿Cómo comprobar el resultado del filtro no es nulo o indefinido? 09 feb. 162016-02-09 08:49:57

  0

Utilicé esta variante de HTML porque estaba seguro de que existía un resultado. Intenté y si no hay ningún resultado, la consola no muestra ningún error, simplemente deja el texto en blanco. Si necesitas hacer algo de lógica si no se encuentran resultados, entonces creo que la mejor manera de hacerlo es la respuesta de Willemoes (código js dentro del controlador). En ese ejemplo, debe verificar en HTML si la variable single_object es nula o indefinida. 09 feb. 162016-02-09 09:19:28

  0

okay. Gracias Ena. 09 feb. 162016-02-09 09:30:03

+2

{{(FooController.results | filter: {id: 1}) [0] .name}: true} - si alguien está buscando una coincidencia exacta 25 abr. 162016-04-25 14:19:51


26

Para cualquier persona que vea esta publicación anterior, esta es la forma más fácil de hacerlo actualmente. Solo requiere un AngularJS $filter. Es como la respuesta de Willemoes, pero más corta y más fácil de entender.

{ 
    "results": [ 
     { 
      "id": 1, 
      "name": "Test" 
     }, 
     { 
      "id": 2, 
      "name": "Beispiel" 
     }, 
     { 
      "id": 3, 
      "name": "Sample" 
     } 
    ] 
} 

var object_by_id = $filter('filter')(foo.results, {id: 2 })[0]; 
// Returns { id: 2, name: "Beispiel" } 

ADVERTENCIA

Como @mpgn dice, este no funciona correctamente. Esto atrapará más resultados.Ejemplo:cuando se busca 3 esta se pondrá al día 23 también

+1

también capture id: 24 12 222 2002 etc 22 sep. 162016-09-22 17:33:22

  0

Creo que ' [0] 'haría que devolviera el primer resultado que encuentre de la colección, por lo que solo funcionaría si su colección está ordenada y el objeto que está buscando es el primero que encuentra durante su iteración. P.ej. si hay un id: 12 que viene antes de id: 2, devolvería id: 12. 08 nov. 172017-11-08 18:22:26


8

Si desea que la lista de artículos como la ciudad sobre la base de la identificación del estado luego usar

var state_Id = 5; 
var items = ($filter('filter')(citylist, {stateId: state_Id })); 

0

utilización $ de tiempo de espera y de ejecución una función para buscar en la matriz de "resultados"

app.controller("Search", function ($scope, $timeout) { 
     var foo = { "results": [ 
      { 
      "id": 12, 
      "name": "Test" 
      }, 
      { 
      "id": 2, 
      "name": "Beispiel" 
      }, 
      { 
      "id": 3, 
      "name": "Sample" 
      } 
     ] }; 
     $timeout(function() { 
      for (var i = 0; i < foo.results.length; i++) { 
       if (foo.results[i].id=== 2) { 
        $scope.name = foo.results[i].name; 
       } 
      } 
     }, 10); 

    }); 

3

¿Por qué complicar la situación? esto es simple escribir una función como esta:

function findBySpecField(data, reqField, value, resField) { 
    var container = data; 
    for (var i = 0; i < container.length; i++) { 
     if (container[i][reqField] == value) { 
      return(container[i][resField]); 
     } 
    } 
    return ''; 
} 

Caso de uso:

var data=[{ 
      "id": 502100, 
      "name": "Bərdə filialı" 
     }, 
     { 
      "id": 502122 
      "name": "10 saylı filialı" 
     }, 
     { 
      "id": 503176 
      "name": "5 sayli filialı" 
     }] 

console.log('Result is '+findBySpecField(data,'id','502100','name')); 

de salida:

Result is Bərdə filialı 

3
$scope.olkes = [{'id':11, 'name':'---Zəhmət olmasa seçim edin---'}, 
       {'id':15, 'name':'Türkyə'}, 
       {'id':45, 'name':'Azərbaycan'}, 
       {'id':60, 'name':'Rusya'}, 
       {'id':64, 'name':'Gürcüstan'}, 
       {'id':65, 'name':'Qazaxıstan'}]; 

<span>{{(olkes | filter: {id:45})[0].name}}</span> 

de salida: Azərbaycan


2

Sé que soy demasiado tarde para responder, pero siempre es mejor para cómo subir en lugar de no aparecer en absoluto :). ES6 manera de conseguirlo:

$http.get("data/SampleData.json").then(response => { 
let id = 'xyz'; 
let item = response.data.results.find(result => result.id === id); 
console.log(item); //your desired item 
}); 

0

La forma más sencilla de obtener elemento (uno) de la matriz por id:

El método find() devuelve el valor del primer elemento de la matriz que satisface la proporcionada función de prueba. De lo contrario, se devuelve indefinido.

function isBigEnough(element) { 
    return element >= 15; 
} 

var integers = [12, 5, 8, 130, 160, 44]; 
integers.find(isBigEnough); // 130 only one element - first 

que no es necesario utilizar el filtro() y ponerse al primer elemento de xx.filter() [0] al igual que en los comentarios anteriores

Lo mismo para los objetos en serie

var foo = { 
"results" : [{ 
    "id" : 1, 
    "name" : "Test" 
}, { 
    "id" : 2, 
    "name" : "Beispiel" 
}, { 
    "id" : 3, 
    "name" : "Sample" 
} 
]}; 

var secondElement = foo.results.find(function(item){ 
    return item.id == 2; 
}); 

var json = JSON.stringify(secondElement); 
console.log(json); 

Por supuesto, si tiene múltiples identificaciones, utilice el método filter() para obtener todos los objetos. Saludos

function isBigEnough(element) { 
 
    return element >= 15; 
 
} 
 

 
var integers = [12, 5, 8, 130, 160, 44]; 
 
integers.find(isBigEnough); // 130 only one element - first

var foo = { 
 
"results" : [{ 
 
    "id" : 1, 
 
    "name" : "Test" 
 
}, { 
 
    "id" : 2, 
 
    "name" : "Beispiel" 
 
}, { 
 
    "id" : 3, 
 
    "name" : "Sample" 
 
} 
 
]}; 
 

 
var secondElement = foo.results.find(function(item){ 
 
    return item.id == 2; 
 
}); 
 

 
var json = JSON.stringify(secondElement); 
 
console.log(json);