我有两个数组,如下所示:
array1 = [
{id:1, children: ['a', 'b']},
{id:2, children: ['a', 'b']},
{id:3, children: ['b', 'c']},
{id:4, children: ['c', 'a']},
{id:5, children: ['a', 'b', 'c']}];
array2 = ['a', 'b'];
现在,我想在JS / TS中编写代码,该代码将找到array1的确切对象,其中array 2的子数组的每个元素与array 1的子数组的每个元素完全匹配(顺序无关紧要)。
我尝试使用三个过滤器来解决此问题,这些过滤器还具有数组1和array2之间的子数组长度匹配的附加条件。但是,如果至少有一个元素与那些具有所需数组长度的子数组相匹配,这也会起作用。
如果有人给我解决方案,我将非常感谢。
array1
.filter(a => a.children
.filter(b => array2
.filter(c => b === c)).length === array2.length);
编辑:
在上面的示例中,我实际上将问题简化了一些。在我的实际项目中,这两个数组如下:
const productOrders: ProductOrder[] =
[
{
productId: 1, subProductOrders:
[{subProduct: {subProductId: 1}}, {subProduct:
{subProductId: 2}}]
},
{
productId: 1, subProductOrders:
[{subProduct: {subProductId: 2}}, {subProduct:
{subProductId: 1}}]
},
{
productId: 1, subProductOrders:
[{subProduct: {subProductId: 2}}, {subProduct:
{subProductId: 3}}]
},
{
productId: 1, subProductOrders:
[{subProduct: {subProductId: 1}}, {subProduct:
{subProductId: 2}}, {subProduct: {subProductId: 3}}]
},
];
const matchingCriteria: SubProductOrder[] =
[
[{subProduct: {subProductId: 1}}, {subProduct: {subProductId:
2}}]
];
现在,我想从productOrders数组中找到产品,其中subProductOrders数组的subProductId与matchingCriteria数组的subProductId匹配(顺序无关紧要)。在上面的示例中,尽管subProductsIds无序,但productOrders数组的前两个产品应该匹配
答案 0 :(得分:4)
您可以使用Set
并对照此结构检查孩子。
var array1 = [{ id: 1, children: ['a', 'b'] }, { id: 2, children: ['a', 'b'] }, { id: 3, children: ['b', 'c'] }, { id: 4, children: ['c', 'a'] }, { id: 5, children: ['a', 'b', 'c'] }],
array2 = ['a', 'b'],
set2 = new Set(array2),
result = array1.filter(({ children }) =>
children.length === set2.size && children.every(Set.prototype.has, set2));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
对于更复杂的数据结构,您可以解构所需的部分并对照一组subProductId
进行检查。
const
getId = ({ subProduct: { subProductId } }) => subProductId;
var productOrders = [{ productId: 1, subProductOrders: [{ subProduct: { subProductId: 1 } }, { subProduct: { subProductId: 2 } }] }, { productId: 1, subProductOrders: [{ subProduct: { subProductId: 2 } }, { subProduct: { subProductId: 1 } }] }, { productId: 1, subProductOrders: [{ subProduct: { subProductId: 2 } }, { subProduct: { subProductId: 3 } }] }, { productId: 1, subProductOrders: [{ subProduct: { subProductId: 1 } }, { subProduct: { subProductId: 2 } }, { subProduct: { subProductId: 3 } }] }],
matchingCriteria = [{ subProduct: { subProductId: 1 } }, { subProduct: { subProductId: 2 } }],
set2 = new Set(matchingCriteria.map(getId)),
result = productOrders.filter(({ subProductOrders }) =>
subProductOrders.length === set2.size &&
subProductOrders.every(o => set2.has(getId(o)))
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:1)
您可以在单个过滤器中使用Array#every()
和长度
const arr1 = [
{id:1, children: ['a', 'b']},
{id:2, children: ['a', 'b']},
{id:3, children: ['b', 'c']},
{id:4, children: ['c', 'a']},
{id:5, children: ['a', 'b', 'c']}
];
const arr2 = ['a', 'b'];
const matched = arr1.filter(({children: c}) => c.length === arr2.length && arr2.every(v => c.includes(v)))
console.log(matched)
答案 2 :(得分:0)
array1 = [
{id:1, children: ['a', 'b']},
{id:2, children: ['b', 'a']},
{id:3, children: ['b', 'c']},
{id:4, children: ['c', 'a']},
{id:5, children: ['a', 'b', 'c']}];
array2 = ['a', 'b'];
const x = array1
.map(a => a.children.sort())
.filter(a => a.length === array2.length)
.map(a => a.sort())
.filter(a => JSON.stringify(a)==JSON.stringify(array2))
console.log(x)
答案 3 :(得分:-1)
您正在根据element.children与array2的相等性过滤array1元素。 因此,我鼓励您看一下这些answers。因为它讨论了javascript中两个数组的相等性。
并根据您的需要修改以下代码,这只是最简单的选项之一:
array1.filter((element,index) => {
return JSON.stringify(element.children) === JSON.stringify(array2)
})