查找两个数组之间的预定义组合
Find Pre-defined Combinations Between Two Arrays
我有一个对象和一个数组:
"catalog" : {
"thing" : {
"required_components" : [ "a", "d" ]
},
"gadget" : {
"required_components" : [ "e", "e" ]
},
"device" : {
"required_components" : [ "d", "e" ]
},
"entity" : {
"required_components" : [ "a", "a" ]
}
}
myComponents = ["a", "d", "c", "a", "e"]
鉴于 myComponents
中列出的组件,我想创建一个可能的目录项数组。
我目前正在遍历 catalog
并使用 .filter()
获取 myComponents
和 required_components
的交集:
console.log(requiredComponents.filter(x => myComponents.includes(x))) //Outputs ["a", "d"]
然后如果 requiredComponents.filter(x => myComponents.includes(x)).length == 2
,我将当前迭代的目录项推送到一个数组。
但这看起来很笨拙,并且会产生一些不希望的和意外的结果。
首先,因为我是在一个循环中进行的,所以它会将多个重复项推送到数组中。我可以用更笨重的代码来克服这个问题。
其次,我最终得到了我没有组件的目录项。例如,如果我有 ["a", "a"]
我会以某种方式在我的输出数组中以 thing
结束。也许这与它也在循环中发生的事实有关。
无论如何,必须有更简洁的方法来做到这一点。
let catalog = [["a", "d"],["e", "e"], ["d","e"], ["a", "a"]];
let myComponents = ["a", "d", "c", "a"];
let possibleComponents = [];
catalog.forEach(item => {
possibleComponents.push(item.filter(x => myComponents.includes(x)));
});
console.log(possibleComponents);
问题似乎来自比较数组时的重复项。
这是一个带有 lodash 的简短原型:
import _ from 'lodash'
// Check if subset is included in superset (respecting duplicates).
const isSubset = (subset, superset) => {
const subsetCount = _.countBy(subset)
const supersetCount = _.countBy(superset)
return _.every(subsetCount, (count, value) => supersetCount[value] >= count)
}
// Filter all catalog items, that could be build by myComponents
const matches = _.pickBy(catalog, ({required_components}, thing) => isSubset(required_components, myComponents))
// Get only the names of the catalog items
const names = _.keys(matches)
我有一个对象和一个数组:
"catalog" : {
"thing" : {
"required_components" : [ "a", "d" ]
},
"gadget" : {
"required_components" : [ "e", "e" ]
},
"device" : {
"required_components" : [ "d", "e" ]
},
"entity" : {
"required_components" : [ "a", "a" ]
}
}
myComponents = ["a", "d", "c", "a", "e"]
鉴于 myComponents
中列出的组件,我想创建一个可能的目录项数组。
我目前正在遍历 catalog
并使用 .filter()
获取 myComponents
和 required_components
的交集:
console.log(requiredComponents.filter(x => myComponents.includes(x))) //Outputs ["a", "d"]
然后如果 requiredComponents.filter(x => myComponents.includes(x)).length == 2
,我将当前迭代的目录项推送到一个数组。
但这看起来很笨拙,并且会产生一些不希望的和意外的结果。
首先,因为我是在一个循环中进行的,所以它会将多个重复项推送到数组中。我可以用更笨重的代码来克服这个问题。
其次,我最终得到了我没有组件的目录项。例如,如果我有 ["a", "a"]
我会以某种方式在我的输出数组中以 thing
结束。也许这与它也在循环中发生的事实有关。
无论如何,必须有更简洁的方法来做到这一点。
let catalog = [["a", "d"],["e", "e"], ["d","e"], ["a", "a"]];
let myComponents = ["a", "d", "c", "a"];
let possibleComponents = [];
catalog.forEach(item => {
possibleComponents.push(item.filter(x => myComponents.includes(x)));
});
console.log(possibleComponents);
问题似乎来自比较数组时的重复项。
这是一个带有 lodash 的简短原型:
import _ from 'lodash'
// Check if subset is included in superset (respecting duplicates).
const isSubset = (subset, superset) => {
const subsetCount = _.countBy(subset)
const supersetCount = _.countBy(superset)
return _.every(subsetCount, (count, value) => supersetCount[value] >= count)
}
// Filter all catalog items, that could be build by myComponents
const matches = _.pickBy(catalog, ({required_components}, thing) => isSubset(required_components, myComponents))
// Get only the names of the catalog items
const names = _.keys(matches)