【问题标题】:Extract deeply nested child objects by property name with lodash [duplicate]使用lodash按属性名称提取深度嵌套的子对象[重复]
【发布时间】:2016-02-01 18:33:00
【问题描述】:

我有深度嵌套的对象数组。我想编写一个函数来从这些数组中提取任意子对象。在某些情况下,嵌套属性的值是值和对象,在其他情况下,它们是数组。

数组示例如下:

[{parent: {level1: {level2: 'data'}}}]

[{parent: {level1: [{level2: {...}}, {level2: {...}}, {level2: {...}}]}}]

[{parent: {level1: [{level2: {level3: 'data'}}, {level2: {..}}, {level2: {..}}]}}]

在这样一个数组上调用提取函数应该会产生一个我们感兴趣的对象数组。

上述示例数组的函数调用示例及其结果:

extractChildren(source, 'level2') = [{level2: 'data'}]

extractChildren(source, 'level2') = [{level2: {...}, level2: {...}, level2: {...}]

extractChildren(source, 'level3') = [{level3: 'data'}]

有没有一种简洁的方法可以使用lodash 来实现这一点,或者我应该使用常规 JavaScript 来遍历属性?

附:将其视为等同于 XPath select all nodes with the name "nodename"

【问题讨论】:

  • 您还应该举例说明应该准确提取哪些子对象,特别是如果一个潜在目标包含另一个潜在目标,结果应该是什么样子。
  • 请显示更多。你能提供预期的输入、“调用”和预期的输出吗?
  • 您的示例无效,您不能在同一级别保留多个具有相同键的项目。
  • @Festo 那些有不同的示例数组
  • @kyrylkov 与您的最新更新,是的 ;)

标签: javascript lodash


【解决方案1】:

希望对你有帮助:

'use strict';

let _ = require("lodash");
let source = [{parent: {level1: [{level2: {level3: 'data'}}, {level2: {}}, {level2: {}}]}}];

function extractChildren(source, specKey) {
    let results = [];
    let search = function(source, specKey) {
        _.forEach(source, function(item) {
            if (!!item[specKey]) {
                let obj = {};
                obj[specKey] = item[specKey];
                results.push(obj);
                return;
            }

            search(item, specKey);
        });
    };

    search(source, specKey);
    return results;
};

console.log(extractChildren(source, 'level3'));
// [ { level3: 'data' } ]

【讨论】:

  • Maximum call stack size exceeded 结尾,带有默认的 Node.js 配置和我的实际数据
  • 您的数据有多大?
  • 最多 10 层左右,但不是很大(几十 KB),否则我会使用流。没关系。我仍然需要以不同的方式解决问题,因为我还需要从父对象中收集一些数据,而且这种简单的 extractChildren 函数无论如何都不适用于这种情况。
【解决方案2】:

来自this question

优雅:

function find_obj_by_name(obj, key) {
    if( !(obj instanceof Array) ) return [];

    if (key in obj)
        return [obj[key]];

    return _.flatten(_.map(obj, function(v) {
        return typeof v == "object" ? find_obj_by_name(v, key) : [];
    }), true);
}

高效:

function find_obj_by_name(obj, key) {
    if( !(obj instanceof Array) ) return [];

    if (key in obj)
        return [obj[key]];

    var res = [];
    _.forEach(obj, function(v) {
        if (typeof v == "object" && (v = find_obj_by_name(v, key)).length)
            res.push.apply(res, v);
    });
    return res;
}

【讨论】:

  • 使用香草forEach而不是_.forEach可以提高“效率”
  • 另外,我不明白这是什么fn(v, key)。你测试过这个吗? fn 是什么?
  • 我现在看到你复制了另一个answer,更改了它,但没有验证结果。
  • ...是的,我在帖子中引用了另一个答案。也许您没有看到第一行的链接?我也测试了这个答案,所以我不确定你在问什么。
  • 你是认真的吗? fn 是未定义的,所以你怎么可能声称你已经测试过它
猜你喜欢
  • 2020-11-03
  • 2018-07-31
  • 2018-01-03
  • 2021-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多