从AngularJS中的对象数组通过ID获取特定对象


111

我有一个JSON文件,其中包含一些我想在AngularJS网站上访问的数据。现在,我要从数组中仅获取一个对象。因此,我想例如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上做一个等于。也许有更好的方法?
mooonli13年

您应该依靠underscorejs或类似的库进行此类处理。AngularJS是MVVM框架,可能没有api。
维杰·潘德2013年

@marcbaur-您必须迭代数组。即使您使用下划线或类似内容,它的功能也在幕后迭代。
亚当(

1
请为此添加角度代码
Ankush Kondhalkar

Answers:


4

唯一的方法就是遍历数组。显然,如果您确定结果按ID排序,则可以执行二进制搜索


46
...我真的希望阅读此答案后,人们认为对数组进行排序然后进行二进制搜索不是一个好主意。二进制搜索很聪明,可以肯定,但是只有在数组已经排序的情况下,并且实际上是:1.易于实施不佳; 2。如果实施不佳则很难阅读。
Ben Lesh 2013年

4
如果下降者可以激励他们的决定,我将不胜感激。
Antonio E.

1
默认情况下,javascript Array类型具有方法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)

我现在将完全使用该解决方案,因为它与角度或任何其他框架的联系较少。纯Javascript。

角解(旧解)

我旨在通过执行以下操作来解决此问题:

$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 2014年

10
这应该是公认的答案。我脑子里也有同样的问题,这个答案是唯一使用现有AngularJS并正在重新发明轮子的问题。是的,它正在工作。
Zoran P.

4
+1就是被接受的答案。使用角度库的最佳解决方案。
Meki 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

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
还捕获ID:24 12 222 2002等
mpgn

我认为这[0]会导致它返回从集合中找到的第一个结果,因此只有在对集合进行排序并且您要查找的对象是它在迭代过程中找到的第一个结果时,它才起作用。例如。12:如果有一个ID:12号之前出现:2,它会返回ID
的冷冻豌豆的罗迪

25

就我个人而言,我使用下划线...

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

那么“ a”将是您想要的数组中id等于2的行


1
真的很喜欢下划线,但是拥有另一个JavaScript库会更糟吗?
Genuinefafa 2014年

8
请注意,这find可能会返回多个对象。由于我们只想要一个,因此我们可以使用findWherewhich仅返回第一个出现的事件(我们知道这是唯一的出现),例如a = _.findWhere(results, {id: 2})
gregoltsov

16

我只想在Willemoes答案中添加一些内容。直接在HTML内部编写的相同代码如下所示:

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

假设“结果”是FooController的变量,并且您要显示已过滤项目的“名称”属性。


@ Ena-如何检查过滤器的结果不为null或未定义?
阿披耶特(Abhijeet)

我使用此HTML变体,因为我确定结果存在。我尝试过,如果没有结果,则控制台没有给出任何错误,它只是将文本留为空白。如果找不到结果就需要做一些逻辑,那么我认为最好的方法是Willemoes答案(控制器内的js代码)。在该示例中,然后应在HTML中检查single_object变量是否为null或未定义。
Ena

2
{{((FooController.results |过滤器:{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 Reaper

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.jsLo-Dash(后者中的示例):

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


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>

输出:Azərbaycan


2

如果可以的话,请使用数组索引作为ID来设计JSON数据结构。您甚至可以“标准化” JSON数组,只要您可以毫无问题地将数组索引用作“主键”和“外键”(如RDBMS)即可。因此,将来您甚至可以执行以下操作:

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()方法返回满足提供的测试功能的数组中第一个元素的值。否则,返回未定义。

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并运行一个函数来搜索“结果”数组

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];
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.