我具有以下结构:
const dictionary = [
{
words: ["foo", "bar"],
desc: "This is a description"
},
{
words: ["some", "word"],
desc: "This is another description"
}
]
我想访问给定单词的desc
。例如:
getDescription(dictionary, "some") // "This is another description"
我对getDescription
的最初实现是这样的:
function getDescription(list, word) {
return list.find(item => item.words.includes(word)).desc
}
这是一种非常简单的方法,但是我想知道是否可以将list
转换为其他内容以使其更有效率(在速度方面),如果说list
有5000个项目,其中words
的范围是1到5或6。
例如,这种初始转换会有所帮助吗?:
list = list.reduce((acc, item) => ({
...acc,
...item.words.reduce((acc, word) => ({
...acc,
[word]: item.desc
}), {})
}), {}
)
}
它将重复很多描述,但是访问将是即时的(list["some"] // This is another description
)。
这些担心是吗?我会感觉到任何性能的速度差异吗?优化,还是只是浪费时间?
答案 0 :(得分:0)
在dictionary
上进行任何预处理都会提高您的性能。将其转换为对象可以将复杂度从O(n)降低到O(1)。就是说,您应该将字典通过单词转换为Map,因为它们是为此类事物创建的。通常,像Elasticsearch这样的inverted index都是这样工作的。
const dictionary = [
{
words: ["foo", "bar"],
desc: "This is a description"
},
{
words: ["some", "word"],
desc: "This is another description"
}
]
const { pipe, map, reduce } = rubico
const incrementMap = (m, [word, desc]) => {
if (m.has(word)) {
m.get(word).push(desc)
} else {
m.set(word, [desc])
}
return m
}
const flatten = arr => arr.flat(1)
// dictionary_arr => inverted_index
const createInvertedIndex = pipe([
map(({ words, desc }) => map(
word => [word, desc],
)(words)),
flatten,
reduce(incrementMap, new Map()),
])
const maptionary = createInvertedIndex(dictionary)
console.log('maptionary.get(\'some\')', maptionary.get('some'))
<script src="https://unpkg.com/rubico/index.js"></script>
上面的示例使用了我的库rubico。我建议您使用tour更好地了解正在发生的事情。