在我问这个问题之前,我为这个糟糕的标题道歉,但我无法更好地描述它。
我有一个这样创建的对象数组:
var setitems = new Array();
setitems.push({set: "1000", item: "5000"});
setitems.push({set: "1000", item: "5010"});
setitems.push({set: "1000", item: "5020"});
setitems.push({set: "1000", item: "5050"});
setitems.push({set: "1010", item: "5010"});
setitems.push({set: "1010", item: "5020"});
setitems.push({set: "1010", item: "5030"});
setitems.push({set: "1020", item: "5020"});
setitems.push({set: "1020", item: "5040"});
setitems.push({set: "1020", item: "5041"});
setitems.push({set: "1030", item: "5040"});
setitems.push({set: "1030", item: "5041"});
setitems.push({set: "1030", item: "5030"});
setitems.push({set: "1040", item: "5041"});
setitems.push({set: "1040", item: "5042"});
项目和集合处于多对多关系中。
一个简单的字符串数组如下:
var itemlist = new Array();
itemlist.push("5010");
itemlist.push("5020");
// itemlist = ["5010", "5020"];
我需要知道哪些集合包含项目列表中的所有项目。
在这个例子中,它应该返回1000和1010。
每套商品的数量是可变的。
项目列表中的项目数是可变的。
谢谢。
您可以先按集合对项目进行分组,然后检查某个集合是否包含itemList中的每个项目。希望这能有所帮助。
const setitems = [];
setitems.push({set: "1000", item: "5000"});
setitems.push({set: "1000", item: "5010"});
setitems.push({set: "1000", item: "5020"});
setitems.push({set: "1000", item: "5050"});
setitems.push({set: "1010", item: "5010"});
setitems.push({set: "1010", item: "5020"});
setitems.push({set: "1010", item: "5030"});
setitems.push({set: "1020", item: "5020"});
setitems.push({set: "1020", item: "5040"});
setitems.push({set: "1020", item: "5041"});
setitems.push({set: "1030", item: "5040"});
setitems.push({set: "1030", item: "5041"});
setitems.push({set: "1030", item: "5030"});
setitems.push({set: "1040", item: "5041"});
setitems.push({set: "1040", item: "5042"});
const itemlist = [];
itemlist.push("5010");
itemlist.push("5020");
const find = (arr, list) => {
const grouped = arr.reduce((acc, val) => ({ ...acc, [val.set]: (acc[val.set] || []).concat(val.item) }), {});
return Object.keys(grouped).reduce((acc, val) => {
if (list.every(item => grouped[val].includes(item))) acc.push(val);
return acc;
}, []);
};
console.log(find(setitems, itemlist));
您可以使用Set
实例:
// Get an array of Set instances for entries matching itemlist entries
const [first, ...rest] = itemlist.map(item =>
setitems.filter(entry => entry.item === item)
.reduce((s, entry) => s.add(entry.set), new Set())
);
// Get an array of the entries in the first of those Sets that also have entries in all the rest
const result = [...first].filter(set => rest.every(s => s.has(set)));
const setitems = [];
setitems.push({set: "1000", item: "5000"});
setitems.push({set: "1000", item: "5010"});
setitems.push({set: "1000", item: "5020"});
setitems.push({set: "1000", item: "5050"});
setitems.push({set: "1010", item: "5010"});
setitems.push({set: "1010", item: "5020"});
setitems.push({set: "1010", item: "5030"});
setitems.push({set: "1020", item: "5020"});
setitems.push({set: "1020", item: "5040"});
setitems.push({set: "1020", item: "5041"});
setitems.push({set: "1030", item: "5040"});
setitems.push({set: "1030", item: "5041"});
setitems.push({set: "1030", item: "5030"});
setitems.push({set: "1040", item: "5041"});
setitems.push({set: "1040", item: "5042"});
const itemlist = [];
itemlist.push("5010");
itemlist.push("5020");
// Get an array of Set instances for entries matching itemlist entries
const [first, ...rest] = itemlist.map(item =>
setitems.filter(entry => entry.item === item)
.reduce((s, entry) => s.add(entry.set), new Set())
);
// Get an array of the entries in the first of those Sets that also have entries in all the rest
const result = [...first].filter(set => rest.every(s => s.has(set)));
console.log(result);
一个可能的解决方案可能使用两步方法。
在第一步中,创建所有可能的"集合"值列表的映射/表/注册表。
最后一步产生结果。它创建了一个"集合"标识符列表,其中每个相关的"集合"值列表包含另一个提供的值列表的每个值。
一个只有ES5的代码可能看起来是这样的。。。
var setItemList = new Array();
setItemList.push({set: "1000", item: "5000"});
setItemList.push({set: "1000", item: "5010"});
setItemList.push({set: "1000", item: "5020"});
setItemList.push({set: "1000", item: "5050"});
setItemList.push({set: "1010", item: "5010"});
setItemList.push({set: "1010", item: "5020"});
setItemList.push({set: "1010", item: "5030"});
setItemList.push({set: "1020", item: "5020"});
setItemList.push({set: "1020", item: "5040"});
setItemList.push({set: "1020", item: "5041"});
setItemList.push({set: "1030", item: "5040"});
setItemList.push({set: "1030", item: "5041"});
setItemList.push({set: "1030", item: "5030"});
setItemList.push({set: "1040", item: "5041"});
setItemList.push({set: "1040", item: "5042"});
var itemlist = new Array();
itemlist.push("5010");
itemlist.push("5020");
// ... with good old ES-5 do ...
// 1st part of solution ... create a map/table/registry of all possible "set" value lists.
//
function collectAndFillSetValueLists (registry, setItem) {
var key = setItem.set;
var value = setItem.item;
var list = registry[key] || (registry[key] = []); // get or create a "set" item specific list.
// if (!list.includes(value)) {
if (list.indexOf(value) === -1) {
list.push(value);
}
return registry;
}
var setItemsRegistry = setItemList.reduce(collectAndFillSetValueLists, {});
console.log('setItemsRegistry : ', setItemsRegistry);
// 2nd part of solution ... create a list of "set" identifiers where each related
// "set" value list contains every value of another provided value list.
//
function collectSetIdsThatsListsContainEveryValue(collector, setKey) {
var list = collector.registry[setKey];
if (collector.valueList.every(function (setValue) {
return (list.indexOf(setValue) >= 0);
// return list.includes(setValue);
})) {
collector.keyList.push(setKey)
}
return collector;
}
var setIdentifierList = Object.keys(setItemsRegistry).reduce(collectSetIdsThatsListsContainEveryValue, {
registry: setItemsRegistry,
valueList: itemlist,
keyList: []
}).keyList;
console.log('setIdentifierList : ', setIdentifierList);
.as-console-wrapper { max-height: 100%!important; top: 0; }