首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何有效地索引到Javascript对象?

如何有效地索引到Javascript对象?
EN

Stack Overflow用户
提问于 2018-02-11 07:52:50
回答 1查看 50关注 0票数 0

人们是否曾经使用基于DOM的数据存储/检索而不是数组或对象来简化索引?

考虑下面的片段。要将颜色更新为棕色,name=Bob需要Javascript中的两个循环:一个用于团队,另一个用于球员。然后在进行颜色更改之前进行比较,以检查name=Bob。

代码语言:javascript
复制
var obj = {"team1": {
  "player1": {
    "name": "bob",
    "color": "red",
  },
  "player2": {
    "name": "george",
    "color": "blue",
  },
},
"team2": {
  "player1": {
    "name": "bob",
    "color": "orange",
  },
  "player2": {
    "name": "george",
    "color": "green",
  },
}};

for (var i in obj)
  for (var j in obj[i])
    if (obj[i][j]["name"] == 'bob')
      obj[i][j]["color"] = 'brown';
      
console.log(obj); // color changed to brown for the two bobs

但是,如果数据存储在DOM中,例如存储在表单元格" data“属性中,那么用一行name=bob更新颜色就更容易了:

代码语言:javascript
复制
$("td[data-name='bob']").data("color", "brown");

我的javascript对象大约有1000个队,每个队有4-5名队员.为每一种颜色的变化循环整个过程似乎需要很大的开销。而jQuery似乎能够在内存中保存整个DOM (真语句?)直接切到右边的细胞,然后改变颜色。

或者jQuery实际上必须在幕后执行两个循环(或类似的性能成本)才能进行更改?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-11 08:29:20

在执行$("td[data-name='bob']")时,必须迭代DOM。与此相比,数据对象的循环非常简单。与在对象结构中执行简单更新相比,更新DOM中的属性要花费更多的时间。所以你为看上去容易的东西付出了代价。

两个循环确实没有问题:重要的是您需要访问的条目数量。

如果经常发生需要根据播放机名进行更新的情况,那么您甚至可以考虑添加类似索引的数据结构,以便按名称进行更快的访问:

代码语言:javascript
复制
const obj = {"team1": {"player1": {"name": "bob","color": "red"},"player2": {"name": "george","color": "blue"}},"team2": {"player1": {"name": "bob","color": "orange"},"player2": {"name": "george","color": "green"}}};
    
// Create a structure keyed by name
const byName = {};
for (const [team, players] of Object.entries(obj)) {
    for (const [playerId, player] of Object.entries(players)) {
        byName[player.name] = 
            (byName[player.name] || []).concat({team, playerId, player});
    }
}

function updateColorForName(name, color) {
    for (const info of byName[name]) {
        info.player.color = color;
    }
}

// Sample call:
updateColorForName("bob", "brown");
// Show update:
console.log(obj);
代码语言:javascript
复制
.as-console-wrapper { max-height: 100% !important; top: 0; }

为了进一步使用ES6功能,使用更合适的Map实现上述功能。

代码语言:javascript
复制
const obj = {"team1": {"player1": {"name": "bob","color": "red"},"player2": {"name": "george","color": "blue"}},"team2": {"player1": {"name": "bob","color": "orange"},"player2": {"name": "george","color": "green"}}};
    
// Create a Map keyed by name
const byName = new Map();
for (const [team, players] of Object.entries(obj)) {
    for (const [playerId, player] of Object.entries(players)) {
        byName.set(player.name, 
            (byName.get(player.name) || []).concat({team, playerId, player}));
    }
}

function updateColorForName(name, color) {
    for (const info of byName.get(name)) {
        info.player.color = color;
    }
}

// Sample call:
updateColorForName("bob", "brown");
// Show update:
console.log(obj);
代码语言:javascript
复制
.as-console-wrapper { max-height: 100% !important; top: 0; }

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48729489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档