【问题标题】:Find deeply nested JSON property using lodash使用 lodash 查找深度嵌套的 JSON 属性
【发布时间】:2018-01-03 15:28:13
【问题描述】:

我有一个具有以下结构的 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: [...]
  },
  ...
]

我还有一小部分内容 ID arr2 = ['id2','id3']。我需要从 API 请求中搜索数据以查找 arr2 中包含的任何 content_id。

我有一些有效的 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
        }
      })
    })
  })
})

我该如何改进这段代码?

【问题讨论】:

  • 我认为举个例子可能会有所帮助//做你想要实现的东西。您是想以某种方式改变 API 响应,还是根据匹配的内容对象创建新对象。如果你想为每个匹配的对象做一些事情,你的迭代很好,尽管 _.find() 可以帮助删除一个循环。
  • 如果比较为真,我将在找到的content 对象上设置一个属性为真,在父section 对象上设置一个属性为真,在祖父@987654327 上设置一个属性为真@对象:content.owned = truesection.owned = truetop.owned = true

标签: javascript arrays json object lodash


【解决方案1】:

您可以创建一个对已识别的后代属性进行递归迭代的函数。

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>

【讨论】:

    【解决方案2】:

    经过一番思考,我实际上无法为您使用其他 lodash 函数提出更优雅的解决方案。似乎要为每个案例设置拥有的属性,forEach 是要走的路。我可以做的唯一优化是避免使用 lodash,只需使用 vanilla javascript forEach Array 函数,并使用 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;
                }
            });
        });
    });
    

    我个人也偏爱箭头函数语法...

    【讨论】:

      猜你喜欢
      • 2020-01-18
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 2014-06-10
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多