我目前有一个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()
以支持其他功能会更好吗?
谢谢!
答案 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
}