给定我的特定情况,是否有比Array.map()更好的CPU效率的JSON迭代方法?

时间:2019-03-07 19:52:05

标签: javascript arrays json

我目前有一个JavaScript程序,该程序从API遍历JSON。我从JSON需要的唯一变量是mana_cost,它将始终在以下两种数据结构之一中可用:

{
  "data": [
    {
      "mana_cost": "{2}"
    },
    {
      "mana_cost": "{G}"
    },
    //etc...
  ]
}

或...

{
  "data": [
    {
      "card_faces": [
        {
          "mana_cost": "{U}"
        }
      ]
    }
  ]
}

我的程序创建了一个名为possibleManaCosts的数组,该数组在JSON中找到了每个mana_cost unique 值,如下所示:

var obj = JSON.parse(body); //body is the JSON requested from the API
var possibleManaCosts = [];

obj.data.map(function(e) {    
    t = (e.card_faces == undefined) ? e.mana_cost : e.card_faces[0].mana_cost

    if (possibleManaCosts.indexOf(t) == -1) {
        possibleManaCosts.push(t);
    }
});

我的问题是,是否有更有效的CPU解决方案。除了缺少的Array.map()之外,我还能使用任何数组函数吗?削减Array.map()以支持其他功能会更好吗?

谢谢!

3 个答案:

答案 0 :(得分:3)

map / forEach并不能真正得到帮助(如果您不执行投影,则确实应该使用forEach)。您可以将其替换为for循环,但这只会使您非常轻微的速度提高:

var possibleManaCosts = {};

for (var i = 0; i < obj.data.length; i++) {
  t = (e.card_faces == undefined) ? e.mana_cost : e.card_faces[0].mana_cost

  if (possibleManaCosts.indexOf(t) == -1) {
    possibleManaCosts.push(t);
  }
}

更重要的是删除indexOf(t)。除了保留唯一的possibleManaCosts数组之外,还保留一个对象,每个键的值为mana_cost

var possibleManaCosts = {};

for (var i = 0; i < obj.data.length; i++) {
  t = (e.card_faces == undefined) ? e.mana_cost : e.card_faces[0].mana_cost

  possibleManaCosts[t] = true;
}

possibleManaCosts = Object.keys(possibleManaCosts);

但是,除非您遍历很多大数组,否则即使这样也很难引起明显的改善。您应该首先针对可读性进行优化,仅担心相对较小的性能调整,除非您有确凿的证据表明这部分代码正在损害用户体验。 Premature optimization is the root of all evil

答案 1 :(得分:1)

如果无论如何都从json字符串解析它并且没有对象作为输入,那么您可以在解析时执行它,而无需付出额外的努力(正是您的情况)。但是,否则,如果您将对象作为输入并且您正在创建一个json字符串以将其解析回去,那么这种想法就不好了,这样您就可以非常轻松地递归迭代。根据性能,这很糟糕,但是很简单。

var inputStr = `{
      "data": [
        {
          "mana_cost": "{2}"
        },
        {
          "mana_cost": "{G}"
        },
        {
          "nested": { "mana_cost": "{Z}" }
        },
        {
          "mana_cost": "{G}"
        }
      ]
    }`,
    res = {},
    parsedData = JSON.parse(inputStr, (k, v) => {
                    k==="mana_cost" && (res[v] = true);
                    return v;
                  })
 console.log(Object.keys(res));

答案 2 :(得分:0)

问题中提供的第二个示例不是有效的JSON,因此我暂时将其忽略。关于第一个示例,到目前为止,最简单的for循环可能是性能最高的:

var obj = JSON.parse(body);
var costs = {};

for (let i = 0; i < obj.data.length; i++) {
  costs[data.mana_cost] = true; // Or some other value
}