No.18 in BFE.dev, link here Improve a function.
// Given an input of array,
// which is made of items with >= 3 properties
let items = [
{color: 'red', type: 'tv', age: 18},
{color: 'silver', type: 'phone', age: 20},
{color: 'blue', type: 'book', age: 17}
]
// an exclude array made of key value pair
const excludes = [
{k: 'color', v: 'silver'},
{k: 'type', v: 'tv'},
...
]
function excludeItems(items, excludes) {
excludes.forEach( pair => {
items = items.filter(item => item[pair.k] === item[pair.v])
})
return items
}
// What does this function excludeItems do?
// Is this function working as expected ?
// What is the time complexity of this function?
// How would you optimize it ?
There is code question above.
And this question asked four questions, the first one is what does this function excludeItems do, well it is self-explanatory, it wants to exclude items array by excludes array.
The second one is the working expected of this function, so we can check the logic inside of it. And here is a filter function to items, and returns the result that item[pair.k] strictly equals to item[pari.v], so the pair here is each element of excludes, ok, then let’s see the first for loop here, the pair is {k: ‘color’, v: ‘silver’}, and pair.k is color pair.v is silver, so item[color] in first element of items is red, item[silver] is nothing then. So pair.k means the property of item but pair.v is the value of item, they have no any connection, so the result of it will always be empty.
The third question is asking the time complexity of this function. So here we let n be the length of items, m be the length of excludes, and here we can see they all have a for loop, so the time complexity is m times n.
The last question is how would you optimize it. To optimize it, we can start from the data structure of excludes, because now the function find element by using filter, it will cost more time as the data volume become bigger, but if we change it’s data structure into a map or set, the time complexity will become to 1, much quicker.
So here we const an excludeMap equals to new Map(), and then we use for of to loop through excludes , and we use object destructure here, let {k, v}, so if there is no k in excludeMap, just set(k, new Set()), else, excludeMap.get(k) and add(v). So we have finished the preprocessing program here.
After that, we can use filter function directly, and then, use Object.keys to iterate through each element of items to get each key of it, last step, just return the value which doesn’t exist in excludeMap or the value which has key of excludes but doesn’t have the value of it.
Here is our codes.
/**
* @param {object[]} items
* @excludes { Array< {k: string, v: any} >} excludes
*/
/**
* @param {object[]} items
* @param { Array< {k: string, v: any} >} excludes
* @return {object[]}
*/
function excludeItems(items, excludes) {
const excludeMap = new Map()
for (let {k, v} of excludes) {
if (!excludeMap.has(k)) {
excludeMap.set(k, new Set())
}
excludeMap.get(k).add(v)
}
return items.filter(item => {
return Object.keys(item).every(
key => !excludeMap.has(key) || !excludeMap.get(key).has(item[key])
)
})
}

被折叠的 条评论
为什么被折叠?



