I would like to find the most efficient way to search an object, where each value is an array of arrays. The search function would recieve an array [0,1,0], find all items that contain this array, and return an array of matching keys.
var items = {
"bob":[[0,0,0],[0,0,1],[0,1,0]],
"joe":[[0,0,0],[1,1,1],[0,1,0]],
"ike":[[0,0,0],[0,0,2],[1,1,1]]
}
for example
[0,0,0] would return ["bob","joe","ike"][0,1,0] would return ["bob","joe"][1,1,1] would return ["joe","ike"][0,0,2] would return ["ike"]This will get the result that you want, but it may not be the most efficient speedwise. It is short though.
const items = {
bob: [
[0, 0, 0],
[0, 0, 1],
[0, 1, 0],
],
joe: [
[0, 0, 0],
[1, 1, 1],
[0, 1, 0],
],
ike: [
[0, 0, 0],
[0, 0, 2],
[1, 1, 1],
],
};
const test = (items, target) => {
return Object.entries(items)
.filter((item) => {
return item[1].some((list) => {
return (
list.length === target.length &&
list.every((number, index) => {
return number === target[index];
})
);
});
})
.map((item) => {
return item[0];
});
};
console.log(test(items, [0, 0, 0])); // [ 'bob', 'joe', 'ike' ]
console.log(test(items, [0, 1, 0])); // [ 'bob', 'joe' ]
console.log(test(items, [1, 1, 1])); // [ 'joe', 'ike' ]
console.log(test(items, [0, 0, 2])); // [ 'ike' ]
Explanation: Use Object.entries() to get the keys and values of items. Then filter out that list using the some function, where there has to be some array in the value list where the array equals the target array. In this case, to see if the arrays are equal, I checked that the lengths were equal and that all the numbers were equal using every. After the entries list is filtered, we then use map to just get the names out.
Using Object#keys and Array#reduce, iterate over the keys of the object. In every property, create a hash from its value, then using Object#hasOwnProperty, check if the target subarray is in it, which will determine whether to include the current key or not in the resulting list:
const getMatchingProps = (obj = {}, subArr = []) =>
Object.keys(obj).reduce((matchingKeys, key) => {
const hash = obj[key].reduce((acc, arr, i) => ({ ...acc, [arr]: i }), {});
return hash.hasOwnProperty(subArr) ? [...matchingKeys, key] : matchingKeys
}, []);
const items = {
"bob": [[0,0,0],[0,0,1],[0,1,0]],
"joe": [[0,0,0],[1,1,1],[0,1,0]],
"ike": [[0,0,0],[0,0,2],[1,1,1]]
};
console.log( getMatchingProps(items, [0,0,0]).join() );
console.log( getMatchingProps(items, [0,1,0]).join() );
console.log( getMatchingProps(items, [1,1,1]).join() );
console.log( getMatchingProps(items, [0,0,2]).join() );