Dapatkan objek tertentu dengan id dari larik objek di AngularJS


111

Saya memiliki file JSON yang berisi beberapa data yang ingin saya akses di situs web AngularJS saya. Sekarang yang saya inginkan adalah mendapatkan hanya satu objek dari array. Jadi saya ingin misalnya Item dengan id 1.

Datanya terlihat seperti ini:

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

Saya ingin memuat data dengan fungsionalitas AngularJS $ http seperti ini:

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

yang berhasil. Tapi bagaimana sekarang saya bisa mendapatkan objek data tertentu (menurut id) dari array yang saya dapatkan $http.get?

Terima kasih sebelumnya atas bantuan Anda.

Salam Marc


Sudahkah Anda mencobanya sendiri? Jika demikian, dapatkah kami melihat apa yang Anda buat?
simonlchilds

1
Saya tidak tahu cara mana yang terbaik menggunakan AngularJS. Apa yang saya tidak suka adalah mengulang array dan melakukan yang sama pada id. Mungkin ada cara yang lebih baik?
mooonli

Anda harus mengandalkan underscorejs atau pustaka serupa untuk pemrosesan tersebut. AngularJS adalah kerangka kerja MVVM dan mungkin tidak memiliki api untuk ini.
Vijay Pande

@ marcbaur - Anda harus mengulang array. Bahkan jika Anda menggunakan garis bawah, atau sesuatu yang serupa, fungsinya, di balik layar, hanya melakukan iterasi.
Adam

1
tolong tambahkan kode sudut untuk ini
Ankush Kondhalkar

Jawaban:


4

Satu-satunya cara untuk melakukannya adalah dengan melakukan iterasi pada array. Tentunya jika Anda yakin bahwa hasil diurutkan berdasarkan id, Anda dapat melakukan pencarian biner


46
... Saya sangat berharap setelah membaca jawaban ini orang tidak berpikir bahwa mengurutkan array kemudian melakukan pencarian biner adalah ide yang bagus. Pencarian biner memang pintar , tetapi hanya jika array sudah diurutkan, dan kenyataannya adalah: 1. mudah diimplementasikan dengan buruk, 2. Lebih sulit dibaca jika diimplementasikan dengan buruk.
Ben Lesh

4
Saya akan sangat menghargai jika downvoters dapat memotivasi keputusan mereka.
Antonio E.

1
Secara default tipe Array javascript memiliki metode find (). Metode find () mengembalikan nilai elemen pertama dalam larik yang memenuhi fungsi pengujian yang disediakan.
abosancic

246

Menggunakan solusi ES6

Bagi mereka yang masih membaca jawaban ini, jika Anda menggunakan ES6, findmetode tersebut ditambahkan dalam array. Jadi dengan asumsi koleksi yang sama, solusinya adalah:

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

Saya akan benar-benar menggunakan solusi ini sekarang, karena tidak terlalu terikat pada sudut atau kerangka lainnya. Javascript murni.

Solusi sudut (solusi lama)

Saya bertujuan untuk menyelesaikan masalah ini dengan melakukan hal berikut:

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

Contoh kasus penggunaan:

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
Sebenarnya, menurutku begitu! Setelah mengambil array, Anda dapat menggunakan fungsi $ filter untuk memfilter item dengan id yang benar.
flup

10
Ini harus menjadi jawaban yang diterima. Saya memiliki pertanyaan yang sama di kepala saya dan jawaban ini adalah satu-satunya yang menggunakan AngularJS yang ada dan tidak menciptakan kembali roda. Dan ya, itu berhasil.
Zoran P.

4
1 karena ini menjadi jawaban yang diterima. Solusi terbaik menggunakan perpustakaan sudut.
Meki

1
Plunker dengan filter dalam sebuah ekspresi: plnkr.co/edit/yc0uZejGqWTcUVKvI7Tq?p=preview
Aaron Roller

4
Ketahuilah bahwa filter menemukan substring yang tidak peka huruf besar / kecil secara default. Jadi (foo.results, {id: 2}) mengembalikan [{id: 12}, {id: 2}], {id: 222}] tapi (foo.results, function (d) {return d.id == = 2;}) mengembalikan [{id: 2}]
Ryan.lay

26

Bagi siapa pun yang melihat posting lama ini, ini adalah cara termudah untuk melakukannya saat ini. Ini hanya membutuhkan AngularJS $filter. Ini seperti jawaban Willemoes, tapi lebih pendek dan lebih mudah dimengerti.

{ 
    "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" }

PERINGATAN

Seperti yang dikatakan @mpgn, ini tidak berfungsi dengan baik . Ini akan menangkap lebih banyak hasil. Contoh: ketika Anda mencari 3, ini akan menangkap 23 juga


1
juga menangkap id: 24 12 222 2002 dll
mpgn

Saya akan berpikir bahwa [0]akan menyebabkannya mengembalikan hasil pertama yang ditemukannya dari koleksi, jadi itu hanya akan berfungsi jika koleksi Anda diurutkan dan objek yang Anda cari adalah yang pertama ditemukan selama iterasi. Misalnya. jika ada id: 12 yang muncul sebelum id: 2, itu akan mengembalikan id: 12.
Roddy of the Frozen Peas

25

Secara pribadi saya menggunakan garis bawah untuk hal-hal semacam ini ... jadi

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

maka "a" akan menjadi baris yang Anda inginkan dari array Anda di mana id sama dengan 2


1
Saya sangat suka garis bawah, tetapi, apakah lebih buruk jika memiliki pustaka JavaScript lain?
genuinefafa

8
Perhatikan bahwa findberpotensi mengembalikan banyak objek. Karena kita hanya menginginkan satu, kita bisa menggunakan findWhereyang hanya mengembalikan kemunculan pertama (yang kita tahu adalah satu-satunya kemunculan), mis a = _.findWhere(results, {id: 2}).
gregoltsov

16

Saya hanya ingin menambahkan sesuatu ke jawaban Willemoes . Kode yang sama yang ditulis langsung di dalam HTML akan terlihat seperti ini:

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

Mengasumsikan bahwa "hasil" adalah variabel dari FooController Anda dan Anda ingin menampilkan properti "nama" dari item yang difilter.


@ Ena-Bagaimana cara memeriksa hasil filter tidak null atau tidak ditentukan?
Abhijeet

Saya menggunakan varian HTML ini karena saya yakin hasilnya ada. Saya mencoba dan jika tidak ada hasil konsol tidak memberikan kesalahan apa pun, itu hanya membiarkan teks kosong. Jika Anda perlu melakukan beberapa logika jika tidak ada hasil yang ditemukan maka saya pikir cara terbaik untuk melakukannya adalah jawaban Willemoes (kode js di dalam pengontrol). Dalam contoh itu, Anda kemudian harus memeriksa HTML jika variabel single_object adalah null atau undefined.
Ena

2
{{(FooController.results | filter: {id: 1}) [0] .name}: true} - jika seseorang mencari pencocokan tepat
George Sharvadze

12

Anda dapat menggunakan ng-repeatdan memilih data hanya jika data cocok dengan yang Anda cari, ng-show misalnya:

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

2
Jika array Anda memiliki lebih dari jumlah item yang sepele, ini akan membuat banyak cakupan yang tidak perlu yang dapat memperlambat aplikasi Anda.
DIMM Reaper

9

Anda bisa mengulang array Anda:

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

Jika Anda tidak ingin menulis loop yang berantakan ini, Anda dapat mempertimbangkan untuk menggunakan underscore.js atau Lo-Dash (contoh yang terakhir):

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

8

Jika Anda ingin daftar item seperti kota berdasarkan id negara, maka gunakan

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

7

Sayangnya (kecuali saya salah), saya pikir Anda perlu mengulangi objek hasil.

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

Setidaknya dengan cara ini ia akan keluar dari iterasi segera setelah menemukan id yang cocok dengan benar.


Mengapa? Apakah Anda memiliki sesuatu untuk mendukungnya?
simonlchilds

11
Nah, tahukah kamu apa ..? Aku hanya pergi ke ulang membaca Javascript - bagian yang baik untuk melawan argumen Anda dan saya saya salah! Selama ini aku salah melakukannya! Itu belum menyebabkan saya masalah ... belum. Saya telah memperbarui jawaban saya.
simonlchilds

6

Mengapa memperumit situasi? ini sederhana tulis beberapa fungsi seperti ini:

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

Kasus Penggunaan:

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

keluaran:

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>

keluaran: Azərbaycan


2

Jika Anda bisa, rancang struktur data JSON Anda dengan menggunakan indeks array sebagai ID. Anda bahkan dapat "menormalkan" array JSON Anda selama tidak ada masalah dalam menggunakan indeks array sebagai "kunci utama" dan "kunci asing", seperti RDBMS. Karena itu, di masa mendatang, Anda bahkan dapat melakukan hal seperti ini:

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

Ini adalah solusi "By Design" . Untuk kasus Anda, cukup:

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

Tentu saja, jika format ID Anda adalah seperti "XX-0001" yang indeks lariknya 0 , maka Anda dapat melakukan manipulasi string untuk memetakan ID; atau tidak ada yang bisa dilakukan tentang itu kecuali melalui pendekatan iterasi.


2

Saya tahu saya terlambat untuk menjawab tetapi selalu lebih baik untuk datang daripada tidak muncul sama sekali :). Cara ES6 untuk mendapatkannya:

$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

Cara sederhana untuk mendapatkan (satu) elemen dari array dengan id:

Metode find () mengembalikan nilai elemen pertama dalam larik yang memenuhi fungsi pengujian yang disediakan. Jika tidak, undefined dikembalikan.

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

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

Anda tidak perlu menggunakan filter () dan menangkap elemen pertama xx.filter () [0] seperti pada komentar di atas

Hal yang sama untuk objek dalam larik

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

Tentu saja jika Anda memiliki banyak id maka gunakan metode filter () untuk mendapatkan semua objek. Bersulang

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

    });
});

Tidak yakin apakah itu benar-benar bagus, tapi ini membantu saya .. Saya perlu menggunakan $ scope untuk membuatnya bekerja dengan baik.


0

gunakan $ timeout dan jalankan fungsi untuk mencari di array "hasil"

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

Saya akan mengulangi array hasil menggunakan filter angularjs seperti ini:

var foundResultObject = getObjectFromResultsList (hasil, 1);

function getObjectFromResultsList(results, resultIdToRetrieve) {
        return $filter('filter')(results, { id: resultIdToRetrieve }, true)[0];
    }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.