【问题标题】:Optmize flattening of an array of nested json objects in JavaScript [closed]优化 JavaScript 中嵌套 json 对象数组的展平[关闭]
【发布时间】:2016-10-08 23:34:34
【问题描述】:

应该有一个对象的数组,比如

[
     {
        "key_set1": {
            int_val: 3,
            arr_val: [
                1,
                3,
                4
            ]
        }
    },
    {
        "key_set2": {
            string_val: "foo"
        }
    }
  ]

我想将内部对象的键展平到一个新的根对象以在最后得到

{
    "key_set1": {
        "int_val": 3,
        "arr_val": [
            1,
            3,
            4
        ]
    },
    "key_set2": {
        "string_val": "foo"
    }
}

假设

  • 这个嵌套结构可以有 N 层,N > 10
  • 结构是有效的 json 对象而不是 javascript 对象,即它具有 atomit/non atomic 类型,而不是 function 对象类型;
  • 整个输入的 json 文件可以是数百 KBytes;
  • 工作必须在 JavaScript V8 / ECMAScript6 中完成;
  • 处理时间必须是毫秒级
  • 此映射的一种变体,需要解析输入的 json 对象并修改值(如使用map 数组方法)。

我希望使用内置方法(如 forEach 和/或快速迭代器 forwhile 等)获得最优化的解决方案,以实现最佳/最差情况。

【问题讨论】:

  • @p.s.w.g wops 忘记了问题,刚刚添加。我想把它优化到最好。
  • @FelixKling 请澄清:)
  • 我投票决定将此问题作为离题结束,因为它似乎要求进行代码审查。 codereview.stackexchange.com 可能是提出这个问题的更好地方(请参阅他们的指南帮助)。
  • Stack Overflow 主要用于解决编程问题。一般的经验法则是,如果您的代码按原样正常运行,并且问题只是寻求帮助以某种方式优化代码(使其更快、更易读等),那么它可能更适合代码审查。跨度>

标签: javascript json flatten


【解决方案1】:

只要我理解正确,你喜欢将数组替换为对象,并将第一级键作为结果对象的新键。

var array = [{ "key_set1": { int_val: 3, arr_val: [1, 3, 4] } }, { "key_set2": { string_val: "foo" } }],
    object = {};

array.forEach(function (a) {
    var key = Object.keys(a)[0];
    object[key] = a[key];
});

console.log(object);

【讨论】:

  • 我没有做过任何基准测试,但for(var key in a) { object[key] = a[key]; return; } 可能比Object.keys(a)[0] 快​​
  • forEach 是否比map 功能普遍可用?
  • @loretoparisi:可能不是,但.map 有不同的用途(它创建一个新数组)。不要将.map 用于迭代数组,.forEach 就是这样做的。
  • @loretoparisi 为什么您担心可用性?你不是根据问题使用ES6吗?
  • @FelixKling 是的,我知道,但 forEach 来自 Mozilla - 请参阅 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…,它不在 ECMA 中,而在 map 中。也许快速迭代器更好。
【解决方案2】:

如果您“想要将其优化到最佳状态” - 您不应该在您的情况下使用 Array.map,因为它会返回一个新数组。
您只需要快速迭代通过list 数组并填充新的flattened 对象。
考虑以下“优化”解决方案:

var flattened = {}, len = list.length;
while (len--) {
    Object.keys(list[len]).forEach((k) => (flattened[k] = list[len][k]));
}
console.log(JSON.stringify(flattened, 0, 4));

输出:

{
    "key_set2": {
        "string_val": "foo"
    },
    "key_set1": {
        "int_val": 3,
        "arr_val": [
            1,
            3,
            4
        ]
    }
}

【讨论】:

  • 也许直觉上是反的,在我的非正式测试中,原始发帖人的功能完成所需的时间比你的要短。
  • 这是有道理的。我在某处看到while 用于类似类型的迭代任务,它会比for 更快吗?
  • @loretoparisi,它取决于数组项的数量和浏览器,负的while 循环应该比任何“正”循环都快
  • @RomanPerekhrest 假设我们转向node / ECMA6 和数百 KB 的 json 文件(假设在 10KB 和 100KB 之间)。
  • @loretoparisi:我认为最好的办法是使用真实数据比较这里提到的一些方法,因为例如,Roman 的代码在更大的数据集上可能运行得更快。
猜你喜欢
  • 1970-01-01
  • 2023-04-08
  • 2020-07-11
  • 2020-12-22
  • 2021-10-19
  • 2012-05-29
  • 2021-03-22
  • 2020-06-23
相关资源
最近更新 更多