AngularJSのオブジェクトの配列からIDで特定のオブジェクトを取得します


111

AngularJSウェブサイトでアクセスしたいデータを含むJSONファイルがあります。次に、配列からオブジェクトを1つだけ取得します。たとえば、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 2013年

1
さて、AngularJSを使用するのに最適な方法はわかりません。私が気に入らないのは、配列を反復処理し、IDに等号を実行することです。多分もっと良い方法がありますか?
mooonli 2013年

このような処理については、アンダースコアまたは類似のライブラリに依存する必要があります。AngularJSはMVVMフレームワークであり、このためのAPIがない場合があります。
Vijay Pande 2013年

@marcbaur-配列を反復する必要があります。アンダースコアなどを使用している場合でも、その機能は裏で繰り返し行われているだけです。
アダム

1
これに角度コードを追加してください
Ankush Kondhalkar

回答:


4

これを行う唯一の方法は、配列を反復処理することです。もちろん、結果がID順になっていることが確実な場合は、バイナリ検索を実行できます。


46
...この回答を読んだ後、配列をソートしてからバイナリ検索を行うのは良い考えではないと人々が思っていることを心から願っています。バイナリ検索は確かに賢いですが、配列がすでにソートされている場合に限り、実際には次のようになります。1。実装が不十分である、2。実装が不十分であると読みにくい
Ben Lesh 2013年

4
反対投票者が決定を動機付けることができれば私は非常に感謝します。
アントニオE.

1
デフォルトでは、javascript配列型にはメソッドfind()があります。find()メソッドは、指定されたテスト関数を満たす配列の最初の要素の値を返します。
abosancic 2017

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)

Angularやその他のフレームワークとはあまり関係がないので、私は今このソリューションに完全に取り組みます。純粋なJavascript。

Angular solution(古いソリューション)

私は次のようにしてこの問題を解決することを目指しました:

$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を持つアイテムをフィルターで除外できます。
フラップ2014年

10
これは受け入れられる答えになるはずです。私の頭の中にも同じ質問がありましたが、この答えは既存のAngularJSを使用して、車輪を再発明する唯一のものです。そして、はい、それは働いています。
Zoran P.

4
これに対する+1が受け入れられた回答です。角度ライブラリを使用する最適なソリューション。
メキ2014年

1
式にフィルターを使用したプランカー
Aaron Roller

4
フィルタはデフォルトで大文字と小文字を区別しない部分文字列を見つけることに注意してください。したがって、(foo.results、{id:2})は[{id:12}、{id:2}]、{id:222}]を返しますが、(foo.results、function(d){return d.id == = 2;})は[{id:2}]を返します
Ryan.lay 2015

26

この古い投稿を見ている人は、これが現在最も簡単な方法です。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も検索されます


1
キャッチID:24 12 222 2002など
mpgn

私は[0]それがコレクションから見つけた最初の結果を返すと思うので、コレクションがソートされていて、探しているオブジェクトがその反復中に最初に見つけた場合にのみ機能します。例えば。12.:12 IDの前に来る:IDがあるかどう2、それはID返します
冷凍エンドウ豆のロディ

25

個人的に私はこの種のものにアンダースコアを使用しています...

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

次に、「a」は、IDが2に等しい配列の希望する行になります


1
私は本当にアンダースコアが大好きですが、別のJavaScriptライブラリを持っているともっと悪いのでしょうか?
本物のfafa 2014

8
find複数のオブジェクトを返す可能性があることに注意してください。必要なのは1つだけなので、を使用しfindWhereて、最初の発生のみを返すことができます(これが唯一の発生であることがわかっています)a = _.findWhere(results, {id: 2})
gregoltsov 2014

16

Willemoesの回答に何かを追加したいだけです。HTML内に直接記述された同じコードは次のようになります。

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

「結果」がFooControllerの変数であり、フィルタリングされたアイテムの「名前」プロパティを表示するとします。


@ Ena-フィルターの結果をチェックする方法はnullまたは未定義ではありませんか?
Abhijeet

結果が存在することを確信していたので、このHTMLバリアントを使用しました。私が試してみましたが、結果がない場合、コンソールはエラーを出さず、単にテキストを空白のままにします。結果が見つからない場合にロジックを実行する必要がある場合は、Willemoesの回答(コントローラー内のjsコード)が最善の方法だと思います。その例では、single_object変数がnullまたは未定義であるかどうかをHTMLでチェックインする必要があります。
恵那

2
{{(FooController.results | filter:{id:1})[0] .name}:true}-誰かが完全一致を探している場合
George Sharvadze

12

ng-repeatデータを使用して選択できるのは、ng-show たとえば次のように、使用しているものとデータが一致する場合のみです。

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

2
配列に取るに足らない数の項目がある場合、これによりアプリケーションが遅くなる可能性のある不要なスコープが多数作成されます。
DIMMリーパー

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 2013年

11
さて、あなたは何を知っていますか?私はJavascriptを読み直しました-あなたの議論に対抗するための良い部分であり、私間違っています!これまでずっと、私はそれを間違っていました!それでも問題は発生していません... 回答を更新しました。
simonlchilds 2013年

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>

出力:アゼルバイカン


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で配列から(1)要素を取得する簡単な方法:

find()メソッドは、指定されたテスト関数を満たす配列の最初の要素の値を返します。それ以外の場合は、未定義が返されます。

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.