0

Do people ever use DOM-based data storage/retrieval instead of arrays or objects to make the indexing simpler?

Consider the snippet below. To update the color to brown wherever name=Bob requires two loops in Javascript: one for the teams, and one for the players. Then a comparison to check for name=Bob before making the color change.

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

But if the data was stored in the DOM, in table cell "data" attributes for example, it'd be easier to update the color where name=bob with one line of jQuery:

$("td[data-name='bob']").data("color", "brown");

My javascript object has about 1000 teams, with 4-5 players on each team. Looping through the whole thing for each color change seems like a lot of overhead. Whereas the jQuery seems to be able to hold the whole DOM in memory (true statement?) and cut straight to the right cells and make the change in color.

Or doe the jQuery actually have to perform two loops (or similar performance cost) behind the scenes in order to make the change?

2
  • 1
    DOM is for presentation of data, not for storing the data. Commented Feb 11, 2018 at 7:57
  • And yes, jQuery executes a ton of code under the hood to make this change. Commented Feb 11, 2018 at 8:19

1 Answer 1

2

When performing $("td[data-name='bob']") the DOM has to be iterated. Compared to this, the looping over the data object is quite light. Updating the attribute in the DOM is again much more costly in time than performing a simple update in your object structure. So you pay a price for what looks easy.

There really is no problem with two loops: what counts is the number of entries you need to visit.

If it regularly happens that you need to make an update based on the player name, then you could consider to even add an index-like data structure for faster access by name:

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);
.as-console-wrapper { max-height: 100% !important; top: 0; }

To further use the ES6 power, implement the above function with the more suitable Map:

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);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

4 Comments

Why not use a Map for byName? It seems better suited for the job.
Why is Map better suited here? Keys are string, what are the advantages that Map provide over object?
@BrianMcCutchon, I can never do it right :-) When I use a Map in my answer I get asked what is that all about, why not a simple object? Anyway, Map version added. Whether or not that is better is maybe more of a personal taste. MDN has a checklist for help in making the choice. Point 3 in that list seems applicable here to prefer a Map (easier to iterate).
@Hassan It's clearer what's going on and you don't get pollution of properties from Object.prototype.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.