简体   繁体   English

使用lodash查找深度嵌套的JSON属性

[英]Find deeply nested JSON property using lodash

I have a JSON API response with the following structure 我有以下结构的JSON API响应

[
  {
    title: "top1",
    sections: [
      {
        section_title: "section1",
        content: [
          {
            content_title: "title1",
            content_id: "id1"
          },
          {
            content_title: "title2",
            content_id: "id2"
          }
        ]
      },
      {
        section_title: "section2",
        content: [
          {
            content_title: "title3",
            content_id: "id3"
          },
          {
            content_title: "title4",
            content_id: "id4"
          }
        ]
      }
    ]
  }, {
    title: "top2",
    sections: [...]
  },
  ...
]

I also have a small array of content IDs arr2 = ['id2','id3'] . 我还有一小部分内容ID arr2 = ['id2','id3'] I need to search the data from the API request to find any content_id that is contained in arr2 . 我需要从API请求中搜索数据,以找到arr2包含的任何content_id。

I have some working lodash code, but my approach of nested forEach does not seem to be the most efficient approach: 我有一些工作的lodash代码,但是我的嵌套forEach方法似乎并不是最有效的方法:

_.forEach(response, function(top) {
  _.forEach(top.sections, function(section) {
    _.forEach(section.content, function(content) {
      _.forEach(arr2, function(id) {
        if(id === content.content_id) {
         // Do stuff
        }
      })
    })
  })
})

How could I improve this code? 我如何改善此代码?

After a little thought, I actually can't come up with a more elegant solution using other lodash functions for you. 经过一番思考,我实际上无法为您提供使用其他lodash函数的更优雅的解决方案。 It seems that to set the owned properties for each and every case the forEach is the way to go. 似乎为每种情况设置拥有的属性都是forEach的。 The only optimisation I can make is to avoid using lodash simply by using the vanilla javascript forEach Array function, and use find to replace the innermost forEach (might make a slight performance improvement). 我唯一可以做的优化就是避免通过简单地使用香草javascript forEach Array函数来使用lodash,并使用find替换最里面的forEach(可能会稍微改善性能)。

response.forEach((topItem) => {
    topItem.sections.forEach((section) => {
        section.content.forEach((content) => {
            if(arr2.find((item) => { return item === content.content_id; })){
                topItem.owned = true; section.owned = true; content.owned = true;
            }
        });
    });
});

I have a personal preference for arrow function syntax also... 我对箭头函数语法也有个人偏好...

You can create a function that recursively iterates over recognized descendant properties. 您可以创建一个函数,该函数以递归方式遍历已识别的后代属性。

function deepWalk(collection, childKeys, iteratee) {

  // create a partial _.each with an iterator that will
  // recursively traverse properties from the `childKeys` array
  var each = _.partial(_.each, _, function(value, index) {
    // invoke iteratee callback
    iteratee(value, index);
    // only recursively iterate over properties found in childKeys
    _(value).pick(childKeys).each(each);
  });

  // invoke iteration
  each(collection);

}

deepWalk(collection, ['sections', 'content'], function(value) {
  if(_.includes(['id2', 'id3'], value.content_id)) {
    // do whatever you want here..
    console.log(value);
  }
});

 var collection = [ { title: "top1", sections: [ { section_title: "section1", content: [ { content_title: "title1", content_id: "id1" }, { content_title: "title2", content_id: "id2" } ] }, { section_title: "section2", content: [ { content_title: "title3", content_id: "id3" }, { content_title: "title4", content_id: "id4" } ] } ] } ]; function deepWalk(collection, childKeys, iteratee) { // create a partial _.each with an iterator that will // recursively traverse properties from the `childKeys` array var each = _.partial(_.each, _, function(value, index) { // invoke iteratee callback iteratee(value, index); // only recursively iterate over properties found in childKeys _(value).pick(childKeys).each(each); }); // invoke iteration each(collection); } deepWalk(collection, ['sections', 'content'], function(value) { if(_.includes(['id2', 'id3'], value.content_id)) { // do whatever you want here.. console.log(value); } }); 
 .as-console-wrapper { min-height: 100%; top: 0; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM