0

I come up with this solution to compare a string to an array of object. However, I don't think this is the best solution. Any suggestion on how to make this function perform better for large array of object?

var a = "blAh";
var b = [{
  "tag": "tag1",
  "icons": ["blah"]
}, {
  "tag": "tag2",
  "icons": ["Blah", "apple", "banana", "bLaH"]
}];

// Desired output "tag1, tag2"
function getTitle(tags, icon) {
  let arr = [];
  for (var i = 0; i < tags.length; i++) {
    tags[i].icons.forEach(elem => {
      if (icon.toLowerCase() === elem.toLowerCase()) {
        if (!arr.includes(tags[i].tag)) {
          arr.push(tags[i].tag);
        }
      }
    });
  }

  return arr.join(', ');
}
console.log(getTitle(b, a));

3
  • You can do icon = icon.toLowerCase() before entering the loop, but what is your actual issue? Lookup speed can be greatly increased using an index, but building the index is additional overhead. You could also build an index of stored values so instead of !arr.includes(tags[i].tag) you'd have a property lookup: !(tags[i].tag in seenValues), etc. Commented May 4, 2017 at 23:15
  • The only improvment I guess is to put icon.toLowerCase() at the very begining of the function (store it in a variable so you won't call it over and over again). If you are looking for an improvment in readability not performance, then use reduce, filter and concat, ... Commented May 4, 2017 at 23:15
  • 1
    @ibrahimmahrir—this is where it goes to opinion: loops are very good for performance and quite readable. Array extras can reduce typing though. ;-) Commented May 4, 2017 at 23:17

1 Answer 1

1

for readability, I would use the following :

var res = b.filter(el =>
  el.icons.length < 0 
    ? false
    : el.icons.map(icon =>  icon.toLowerCase()).indexOf(a.toLocaleLowerCase()) != -1
).map(el => el.tag).join(', ');

But for performances, this one would be better :

var res = [];
var i, j;
for (i = 0; i < b.length; i++) {
  if (b[i].icons.length < 0) {
  } else {
     for (j = 0; j < b[i].icons.length; j++)
       b[i].icons[j] = b[i].icons[j].toLowerCase();
    if (b[i].icons.indexOf(a.toLocaleLowerCase()) !== -1)
      res.push(b[i].tag);
  }
}
res = res.join(', ');

Here is why :

  • indexOf is always faster than includes (or equal in old versions of chrome). benchmark
  • for loops are always faster than array methods like filter, map or reduce. benchmarks : map, filter

Also it's intresting to see that for loops are faster than indexOf in the latest version of chrome (60)

Hope it helps,
Best regards

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.