我正在使用.js和lodash
我需要能够在对象中执行深度搜索(深度和键可能会有所不同)。例如:
这是我执行搜索所需的数据集:
const data = [
object1: {
key1: {
level1: {
filter: "this is a value"
},
junk: "..."
},
key2: {
level1:{
filter: ".."
}
junk: "this is complicated"
},
...
},
object2: { ... },
object3: { ... }
]这是我的搜索条件,其中包括数据集中对象的一些属性,如果值为true,我将使用它作为筛选器来筛选出数据
const searchCriteria = {
key1: {
level1: {
filter: true,
someOherFilter: false
}
},
key2: {
junk: true
},
...
} 所以正如你所看到的,我不能依赖于键的名称,我只需要从搜索条件中检索所有的"true“值,使用它们作为链式过滤器,并搜索数据集,当它们匹配时,我将返回整个对象。
我可以使用以下命令从searchCriteria中找到真实值:const selectedFilters = _.keys(_.pickBy(filter, _.identity))只需将过滤器应用于对象
现在我只剩下一个包含过滤器的数组:[filter] or [junk]
我们使用的是lodash,我用了相当多的plucks,地图,过滤器,还有查找..但没能得到我想要的。
所以假设我得到的搜索条件是:["key1", "level1", "filter],或者我可能得到的是["key2", "junk"]。
编写深度搜索函数的最佳方式是什么,最好使用lodash?
发布于 2017-05-19 14:47:19
不使用lodash的解决方案:
在这里,getKeyByPathArr有两个参数:键级别的object和array,如果键不存在或参数不正确,则返回value或null。
// @param o <object>
// @param pathArr <array> of key levels
// @return o[key] value where key = pathArr.join(.) and value exists,
// otherwise return null. If pathArr === [] return o
const getKeyByPathArr = o => pathArr => (Array.isArray(pathArr))
? pathArr.reduce((a, c) => (a[c] != null) ? a[c] : null, o)
: null;
const data = {
object1: {
key1: { level1: { filter: "this is a value" } },
key2: { junk: "this is complicated" },
},
object2: {},
object3: {}
};
const keys1 = ["key1", "level1", "filter"];
const keys2 = ["key2", "junk"];
const result1 = getKeyByPathArr(data.object1)(keys1);
const result2 = getKeyByPathArr(data.object1)(keys2);
console.log(result1)
console.log(result2)
发布于 2017-05-19 14:59:18
由于你的数据可能是一个很大的列表,你最好先从searchCriteria初始化你的过滤器。
1递归遍历searchCriteria,如果最深的布尔值为true,则输出该过滤器的路径:
// getters
`searchCriteria` => [ _.property('key1.level1.filter'), _.property('key1.level1.otherFilter')]2使用step1中的getters过滤数据中的对象
_.filter(data, obj => _.some(getters, getter => !!getter(obj))) // etc.https://stackoverflow.com/questions/44062691
复制相似问题