Ответ 1
Единственный способ сделать это - перебрать массив. Очевидно, если вы уверены, что результаты упорядочены по id, вы можете сделать двоичный поиск
У меня есть файл JSON, содержащий некоторые данные, которые я хотел бы получить на моем сайте AngularJS. Теперь я хочу получить только один объект из массива. Так что я хотел бы, например, Item с идентификатором 1.
Данные выглядят следующим образом:
{ "results": [
{
"id": 1,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] }
Мне нравится загружать данные с помощью функции AngularJS $http, например:
$http.get("data/SampleData.json");
который работает. Но как я могу теперь получить конкретный объект данных (по id) из массива, который я получаю из $http.get
?
Заранее благодарим за помощь.
здоровается Марк
Единственный способ сделать это - перебрать массив. Очевидно, если вы уверены, что результаты упорядочены по id, вы можете сделать двоичный поиск
Использование решения ES6
Для тех, кто все еще читает этот ответ, если вы используете ES6, метод find
был добавлен в массивы. Таким образом, если принять ту же коллекцию, решение должно быть:
const foo = { "results": [
{
"id": 12,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] };
foo.results.find(item => item.id === 2)
Теперь я полностью решил бы это решение, так как оно меньше привязано к angular или к любой другой структуре. Чистый Javascript.
Angular решение (старое решение)
Я решил решить эту проблему, выполнив следующие действия:
$filter('filter')(foo.results, {id: 1})[0];
Пример использования:
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
Для тех, кто смотрит на это старое сообщение, это самый простой способ сделать это в настоящее время. Для этого требуется только AngularJS $filter
. Его, как Виллемо, отвечают, но короче и понятнее.
{
"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" }
Внимание
Как говорит @mpgn, этот работает неправильно. Это приведет к большим результатам. Пример:, когда вы выполняете поиск 3, это тоже поймает 23
лично я использую подчеркивание для такого рода вещей... так
a = _.find(results,function(rw){ return rw.id == 2 });
тогда "a" будет строкой, которую вы хотели получить от вашего массива, где идентификатор был равен 2
Я просто хочу добавить что-то в ответ Виллемо. Тот же код, написанный непосредственно внутри HTML, будет выглядеть так:
{{(FooController.results | filter : {id: 1})[0].name }}
Предполагая, что "результаты" являются переменной вашего FooController, и вы хотите отобразить свойство "name" отфильтрованного элемента.
Вы можете использовать ng-repeat
и выбирать данные только в том случае, если данные соответствуют тому, что вы ищете, используя ng-show
например:
<div ng-repeat="data in res.results" ng-show="data.id==1">
{{data.name}}
</div>
Вы можете просто перебрать ваш массив:
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);
Если вы не хотите писать эти беспорядочные циклы, вы можете использовать underscore.js или Lo-Dash (пример в последнем):
var doc_id_2 = _.filter(doc.results, {id: 2})[0]
Если вам нужен список предметов, таких как город, на основе идентификатора состояния, используйте
var state_Id = 5;
var items = ($filter('filter')(citylist, {stateId: state_Id }));
К сожалению (если я не ошибаюсь), я думаю, вам нужно перебирать объект результатов.
for(var i = 0; i < results.length; i += 1){
var result = results[i];
if(result.id === id){
return result;
}
}
По крайней мере, так он выйдет из итерации, как только найдет правильный идентификатор соответствия.
Зачем усложнять ситуацию? это просто написать некоторую функцию следующим образом:
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 '';
}
Случай использования:
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'));
выход:
Result is Bərdə filialı
$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>
вывод: Azərbaycan
Если это возможно, создайте структуру данных JSON, используя индексы массива в качестве идентификаторов. Вы даже можете "нормализовать" свои массивы JSON, если у вас нет проблем с использованием индексов массива как "первичный ключ" и "внешний ключ", что-то вроде РСУБД. Таким образом, в будущем вы можете даже сделать что-то вроде этого:
function getParentById(childID) {
var parentObject = parentArray[childArray[childID].parentID];
return parentObject;
}
Это решение "По дизайну" . Для вашего случая просто:
var nameToFind = results[idToQuery - 1].name;
Конечно, если ваш ID-формат похож на "XX-0001" , индекс индекса массива которого 0, то вы можете либо выполнить некоторые манипуляции с строкой для отображения идентификатор; или иначе ничего нельзя сделать по этому поводу, кроме как с помощью итерационного подхода.
Я знаю, что слишком поздно ответить, но всегда лучше появляться, а не появляться вообще:). Способ ES6:
$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
});
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;
}
}
});
});
Не уверен, что это действительно хорошо, но это было полезно для меня.. Мне нужно было использовать $scope, чтобы он работал правильно.
используйте $timeout и запустите функцию для поиска в массиве результатов
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);
});
Простой способ получить (один) элемент из массива по id:
Метод find() возвращает значение первого элемента в массиве, который удовлетворяет предоставленной функции тестирования. В противном случае возвращается undefined.
function isBigEnough(element) {
return element >= 15;
}
var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130 only one element - first
вам не нужно использовать filter() и улавливать первый элемент xx.filter() [0], как в комментариях выше
То же самое для объектов в массиве
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);
Конечно, если у вас есть несколько идентификаторов, используйте метод filter() для получения всех объектов. Приветствия
function isBigEnough(element) {
return element >= 15;
}
var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130 only one element - first