如何使用具有特定属性的嵌套对象获取计数

How can get a count with nested objects with a certain property?

本文关键字:对象 嵌套 获取 属性 何使用      更新时间:2023-09-26

好的,所以我使用angular将json保存到我的计算机上,以重新创建github gradebook。

我可以通过$http请求获得数据,但出于我的爱,我只想用标签"尚未"来统计问题的数量。

这是javascript:

$http.get('/api/github/repos/issues/all_issues/00All.json')
  .then(function(response) {
    console.log(response.data[0]);
    var counter = 0;
    for(var index = 0; index < response.data.length; index++) {
      if(response.data[index].labels[0].name == "Not Yet") {
        counter++;
      };
    };
    console.log(counter);
  });

这是最近的一次尝试,我也尝试过使用lodash来更早地获得它:

$http.get('/api/github/repos/issues/all_issues/00All.json')
  .then(function(response) {
    console.log(response);
    mile.notYet.width = _.forEach(response.data, function(n){
      var counter = 0;
      if(_.result(_.find(n.labels[0], 'name')) == "Not Yet") {
        counter++;
      }
      console.log(counter);
      counter = ((counter/10) * 100) + '%';
    });
  });

这是一个json数据:

[
  {
    "url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11",
    "labels_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/labels{/name}",
    "comments_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/comments",
    "events_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/events",
    "html_url": "https://github.com/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11",
    "id": 73013825,
    "number": 11,
    "title": "00 -- Brace Yourself -- BEN GRIFFITH",
    "user": {
      "login": "Epicurean306",
      "id": 11682684,
      "avatar_url": "https://avatars.githubusercontent.com/u/11682684?v=3",
      "gravatar_id": "",
      "url": "https://api.github.com/users/Epicurean306",
      "html_url": "https://github.com/Epicurean306",
      "followers_url": "https://api.github.com/users/Epicurean306/followers",
      "following_url": "https://api.github.com/users/Epicurean306/following{/other_user}",
      "gists_url": "https://api.github.com/users/Epicurean306/gists{/gist_id}",
      "starred_url": "https://api.github.com/users/Epicurean306/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/Epicurean306/subscriptions",
      "organizations_url": "https://api.github.com/users/Epicurean306/orgs",
      "repos_url": "https://api.github.com/users/Epicurean306/repos",
      "events_url": "https://api.github.com/users/Epicurean306/events{/privacy}",
      "received_events_url": "https://api.github.com/users/Epicurean306/received_events",
      "type": "User",
      "site_admin": false
    },
    "labels": [
      {
        "url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/labels/Not%20Yet",
        "name": "Not Yet",
        "color": "e11d21"
      }
    ],

正如你所看到的,labels属性是一个对象,嵌套在数组中,嵌套在对象中,嵌套到数组中,真的很可爱。放置标签[0]每次都会导致一个错误,并且不会得到计数。有人能告诉我我在哪里搞砸了吗?非常感谢。

如果您需要一个包含lodash的解决方案,它比原生高阶函数的性能高得多,那么您可以尝试以下解决方案:

var size = _(response.data)
   .pluck('labels')
   .flatten()
   .where({ name: 'Not Yet' })
   .size();

更新:

如果您希望它更可重复使用,您可以为克隆的链式序列保存一个引用,并简单地为该克隆序列提供另一个数组。

var data1 = [/*array from data1*/];
var data2 = [/*array from data2*/];
var notYetSequence = _(data1)
  .pluck('labels')
  .flatten()
  .where({ name: 'Not Yet' });
notYetSequence.size(); // returns data 1 count
notYetSequence.plant(data2).size(); // returns data 2 count

任务不需要lodash

var cnt = response.data
    .map(function(i) { return i.labels; })
         // here we extract labels object only (and get an array of arrays of objects)
    .map(function(i) { return i.filter(function(l) { return l.name == 'Not yet'; }).length; })
         // then for every nested array we return a number of items with 
         // Not Yet names (and get an array of numbers)
    .filter(function(c) { return c > 0; })
         // then we filter issues that don't have one (and still get an array of numbers)
    .length;
         // and finally get length (which is a number)

作为比较,一个普通的for循环看起来像:

  var data = response.data;
  var count = 0;
  var re = /not yet/i;
  for (var a, i=0, iLen=data.length; i<iLen; i++) {
    a = data[i].labels;
    for (var j=0, jLen=a.length; j<jLen; j++) {
      if (re.test(a[j].name)) ++count;
    }
  }

因此,无论哪种方式,for循环都不会有太多代码,它将与所有浏览器兼容(尽管使用xmlHTTPRequest意味着至少ed3+),而且速度最快……当然未经测试