2017-05-04 238 views
0

我想出了这个解决方案,将一个字符串与一个对象数组进行比较。但是,我不认为这是最好的解决方案。任何关于如何使这个函数对于大量对象更好的建议?将字符串与对象数组进行比较

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));

+0

你可以做'图标= icon.toLowerCase()'进入循环前,但是你的实际问题是什么?使用索引可以大大提高查找速度,但构建索引是额外的开销。你也可以创建一个存储值的索引,而不是'!arr.includes(tags [i] .tag)''''''''''''''''''''''''! – RobG

+0

我猜想唯一的改进就是在函数的开头部分放置'icon.toLowerCase()'(将其存储在一个变量中,这样您就不会一遍又一遍地调用它)。如果你正在寻找一种可读性而不是性能的改进,那么使用'reduce','filter'和'concat',... –

+1

@ ibrahimmahrir-这是它的观点:循环对性能非常好,并且非常易读。尽管数组额外可以减少键入。 ;-) – RobG

回答

1

的可读性,我会用以下内容:

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(', '); 

但对于表演,这一次会更好:

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(', '); 

这是为什么:

  • indexOf始终快于includes(或在老版本的chrome中相同)。 benchmark
  • for循环始终比数组方法(如过滤器,映射或缩减)更快。基准测试:mapfilter

而且它intresting看到for loops are faster than indexOf in the latest version of chrome (60)

希望它能帮助,
最好的问候