AngularJS의 개체 배열에서 ID로 특정 개체 가져 오기


111

AngularJS 웹 사이트에서 액세스하고 싶은 일부 데이터가 포함 된 JSON 파일이 있습니다. 이제 내가 원하는 것은 배열에서 하나의 객체 만 가져 오는 것입니다. 예를 들어 ID가 1 인 항목을 좋아합니다.

데이터는 다음과 같습니다.

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

다음과 같은 AngularJS $ http 기능을 사용하여 데이터를로드하고 싶습니다.

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

작동합니다. 하지만 이제 내가 얻은 배열에서 특정 데이터 객체 (ID 별)를 $http.get어떻게 얻을 수 있습니까?

도움을 주셔서 미리 감사드립니다.

마크 인사


직접 해보 셨나요? 그렇다면 우리는 당신이 무엇을 생각해 냈는지 볼 수 있습니까?
simonlchilds

1
나는 AngularJS를 사용하는 것이 가장 좋은 방법이 무엇인지 모릅니다. 내가 싫어하는 것은 배열을 반복하고 id에서 같음을 수행하는 것입니다. 더 좋은 방법이 있을까요?
mooonli

이러한 처리를 위해서는 underscorejs 또는 유사한 라이브러리를 사용해야합니다. AngularJS는 MVVM 프레임 워크이며이를위한 API가 없을 수 있습니다.
Vijay Pande 2013 년

@marcbaur-배열을 반복해야합니다. 밑줄이나 이와 유사한 것을 사용하더라도 뒤에서 함수는 단지 반복됩니다.
Adam

1
이를 위해 각 코드를 추가하십시오
Ankush Kondhalkar에게

답변:


4

이를 수행하는 유일한 방법은 배열을 반복하는 것입니다. 결과가 ID로 정렬되어 있다고 확신하는 경우 이진 검색을 수행 할 수 있습니다.


46
...이 답변을 읽은 후 사람들이 배열을 정렬하고 이진 검색을 수행하는 것이 좋은 생각이 아니라고 생각합니다. 이진 검색은 영리합니다 .하지만 배열이 이미 정렬되어 있고 실제로는 다음과 같은 경우 에만 가능합니다. 1. 제대로 구현하기 쉬움, 2. 제대로 구현하지 않으면 읽기 어렵습니다.
Ben Lesh 2013 년

4
반대 투표자가 결정에 동기를 부여 할 수 있다면 대단히 감사하겠습니다.
Antonio E.

1
기본적으로 자바 스크립트 배열 유형에는 find () 메소드가 있습니다. find () 메서드는 제공된 테스트 함수를 충족하는 배열의 첫 번째 요소 값을 반환합니다.
abosancic

246

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)

각도 나 다른 프레임 워크에 덜 묶여 있기 때문에 지금은이 솔루션을 선택하겠습니다. 순수 자바 스크립트.

각도 솔루션 (이전 솔루션)

다음을 수행하여이 문제를 해결하고자했습니다.

$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);
}]);

플 런커 : http://plnkr.co/edit/5E7FYqNNqDuqFBlyDqRh?p=preview


1
사실 그렇게 생각합니다! 배열을 가져온 후 $ filter 함수를 사용하여 올바른 ID로 항목을 필터링 할 수 있습니다.
flup

10
이것은 받아 들여진 대답이어야합니다. 나는 내 머리 속에 같은 질문을 가지고 있었고이 대답은 기존 AngularJS를 사용하고 바퀴를 재발 명하고있는 유일한 대답입니다. 그리고 네, 작동합니다.
Zoran P.

4
+1이 허용되는 답변입니다. 각도 라이브러리를 사용하는 최상의 솔루션입니다.
Meki


4
필터는 기본적으로 대소 문자를 구분하지 않는 하위 문자열을 찾습니다. 따라서 (foo.results, {id : 2})는 [{id : 12}, {id : 2}], {id : 222}]를 반환하지만 (foo.results, function (d) {return d.id == = 2}) 복귀 [ID {2}]
Ryan.lay

26

이 오래된 게시물을 보는 사람에게는 현재 가장 쉬운 방법입니다. AngularJS 만 필요합니다 $filter. Willemoes와 비슷하지만 더 짧고 이해하기 쉽습니다.

{ 
    "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도 검색됩니다.


1
또한 catch id : 24 12 222 2002 etc
mpgn

나는 [0]그것이 컬렉션에서 찾은 첫 번째 결과를 반환 하도록 할 것이라고 생각 하므로 컬렉션이 정렬되고 찾고있는 객체가 반복 중에 찾은 첫 번째 객체 인 경우에만 작동합니다. 예 : id : 2 앞에 오는 id : 12가 있으면 id : 12를 반환합니다.
Roddy of the Frozen Peas

25

개인적으로 이런 종류의 경우 밑줄을 사용합니다.

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

그러면 "a"는 id가 2 인 배열에서 원하는 행입니다.


1
나는 밑줄을 정말 좋아 하지만 다른 JavaScript 라이브러리가 있으면 더 나빠질까요?
genuinefafa

8
참고 find잠재적으로 여러 개체를 반환 할 수 있습니다. 우리는 하나만 원하기 때문에 findWhere첫 번째 발생 (우리가 알고있는 유일한 발생) 만 반환하는 것을 사용할 수 있습니다 a = _.findWhere(results, {id: 2}). 예 : .
gregoltsov

16

Willemoes 답변 에 뭔가 추가하고 싶습니다 . HTML 내부에 직접 작성된 동일한 코드는 다음과 같습니다.

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

"결과"가 FooController의 변수라고 가정하고 필터링 된 항목의 "이름"속성을 표시하려고합니다.


@ Ena- 필터의 결과가 null이 아니거나 정의되지 않았는지 확인하는 방법은 무엇입니까?
Abhijeet

결과가 존재한다고 확신했기 때문에이 HTML 변형을 사용했습니다. 시도했지만 결과가 없으면 콘솔에서 오류가 발생하지 않고 텍스트를 비워 둡니다. 결과가 없으면 로직을 수행해야하는 경우 가장 좋은 방법은 Willemoes 답변 (컨트롤러 내부의 js 코드)입니다. 이 예에서는 single_object 변수가 null인지 정의되지 않았는지 HTML을 확인해야합니다.
Ena

2
{{(FooController.results | 필터 : {ID : 1}) [0] .name을} : TRUE} - 누군가의 정확한 일치를 찾는 경우
조지 Sharvadze

12

ng-repeat데이터가 찾고있는 것과 일치하는 경우에만 데이터를 사용 하고 선택할 수 있습니다 ng-show . 예를 들면 다음과 같습니다.

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

2
배열에 사소한 수 이상의 항목이있는 경우 불필요한 범위가 많이 생성되어 애플리케이션 속도가 느려질 수 있습니다.
The DIMM Reaper 2015 년

9

배열을 반복 할 수 있습니다.

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]

8

주 ID를 기준으로 도시와 같은 항목 목록을 원하면 다음을 사용하십시오.

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

7

불행히도 (내가 착각하지 않는 한) 결과 객체를 반복해야한다고 생각합니다.

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

적어도 이런 식으로 올바른 일치 ID를 찾는 즉시 반복에서 벗어날 것입니다.


왜? 백업 할 것이 있습니까?
simonlchilds

11
그거 알아 ..? 당신의 주장에 대응하기 위해 좋은 부품을 난 - 난 그냥 다시 읽기 자바 스크립트에 갔던 나는 잘못! 이 모든 시간 동안 나는 잘못하고 있습니다! 그래도 문제가 발생하지 않았습니다 ... 아직. 내 답변을 업데이트했습니다.
simonlchilds

6

상황을 복잡하게 만드는 이유는 무엇입니까? 다음과 같은 함수를 작성하는 것은 간단합니다.

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ı

4
$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


2

가능한 경우 배열 인덱스를 ID로 사용하여 JSON 데이터 구조를 설계하십시오. RDBMS와 같은 "기본 키"및 "외래 키"로 배열 인덱스를 사용하는 데 문제가없는 한 JSON 배열을 "정규화"할 수도 있습니다. 따라서 앞으로 다음과 같이 할 수도 있습니다.

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

이것이 바로 "설계 별" 솔루션 입니다. 귀하의 경우 간단히 :

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

물론, ID 형식이 "XX-0001" 과 같이 배열 인덱스가 0 인 경우 문자열 조작을 수행하여 ID를 매핑 할 수 있습니다. 그렇지 않으면 반복 접근 방식을 제외하고는 그것에 대해 아무것도 할 수 없습니다.


2

대답하기에는 너무 늦었지만 전혀 나타나지 않는 것보다 항상 나타나는 것이 낫습니다. :). 그것을 얻는 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
});

2

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);

물론 여러 ID가있는 경우 filter () 메서드를 사용하여 모든 개체를 가져옵니다. 건배

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);


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;
        }
        }

    });
});

정말 좋은지는 모르겠지만이게 도움이 됐습니다. 제대로 작동하려면 $ scope를 사용해야했습니다.


0

$ timeout을 사용하고 "results"배열에서 검색하는 함수를 실행하십시오.

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);

    });

0

다음과 같이 angularjs 필터를 사용하여 결과 배열을 반복합니다.

var foundResultObject = getObjectFromResultsList (results, 1);

function getObjectFromResultsList(results, resultIdToRetrieve) {
        return $filter('filter')(results, { id: resultIdToRetrieve }, true)[0];
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.