Reputation: 65
I have a object with others arrays. I need to filter when in the main array match RazaoSocial:"AAS" or Produtos:[{Descricao:"AAS"}]
That's my code:
var input = [
{
RazaoSocial: 'AAS',
Produtos: [
{ DescricaoProduto: 'XXX', id:12, other:"other text" },
{ DescricaoProduto: 'YYY', id:12, other:"other text" }
]
},
{
RazaoSocial: 'I found you',
Produtos: [
{ DescricaoProduto: 'AAS', id:12, other:"other text" },
{ DescricaoProduto: 'Miss8', id:12, other:"other text" },
{ DescricaoProduto: 'Miss8', id:12, other:"other text" },
{ DescricaoProduto: 'Miss8', id:99, other:"other text" }
]
},
{
RazaoSocial: 'bla',
Produtos: [
{ DescricaoProduto: 'AB', id:12, other:"other text" },
{ DescricaoProduto: 'CD', id:12, other:"other text" },
]
},
];
var res = input.filter(function f(o) {
if (o.RazaoSocial.includes("AAS")) return true
if (o.Produtos.DescricaoProduto) {
console.log(o.Produtos);
return (o.Produtos = o.Produtos.filter(f)).length
}
})
console.log(JSON.stringify(res, null, 2));
//result
[
{
"RazaoSocial": "AAS",
"Produtos": [
{
"DescricaoProduto": "XXX",
"id": 12,
"other": "other text"
},
{
"DescricaoProduto": "YYYAAS",
"id": 12,
"other": "other text"
}
]
}
]
Why the object with "i found you" it's not returned ? I was expeting
[
{
RazaoSocial: 'AAS',
Produtos: [
{ DescricaoProduto: 'XXX', id: 12, other: "other text" },
{ DescricaoProduto: 'YYY', id: 12, other: "other text" }
]
},
{
RazaoSocial: 'I found you',
Produtos: [
{ DescricaoProduto: 'AAS', id: 12, other: "other text" },
{ DescricaoProduto: 'Miss8', id: 12, other: "other text" },
{ DescricaoProduto: 'Miss8', id: 12, other: "other text" },
{ DescricaoProduto: 'Miss8', id: 99, other: "other text" }
]
}
]
I tried the examples in, but with no success. Recursively filter array of objects
What I'm doing wrong ?
thanks for the help.
Upvotes: 0
Views: 1251
Reputation: 7926
The main problem with the original attempt was the if (o.Produtos.DescricaoProduto) {
o.Produtos
is an array so you cannot access o.Produtos.DescricaoProduto
without first getting an index.
So since o.Produtos
is an array we can go ahead and filter it like we did the original input.
I've added both a recursive and non-recursive approach you could compare.
The recursive solution is entirely generic and can find any given value.
var input = [
{
RazaoSocial: 'AAS',
Produtos: [
{ DescricaoProduto: 'XXX', id:12, other:"other text" },
{ DescricaoProduto: 'YYY', id:12, other:"other text" }
]
},
{
RazaoSocial: 'I found you',
Produtos: [
{ DescricaoProduto: 'AAS', id:12, other:"other text" },
{ DescricaoProduto: 'Miss8', id:12, other:"other text" },
{ DescricaoProduto: 'Miss8', id:12, other:"other text" },
{ DescricaoProduto: 'Miss8', id:99, other:"other text" }
]
},
{
RazaoSocial: 'bla',
Produtos: [
{ DescricaoProduto: 'AB', id:12, other:"other text" },
{ DescricaoProduto: 'CD', id:12, other:"other text" },
]
},
];
var useRecursive = true,
res;
if (useRecursive) {
var findValue = function (str) {
return function(o) {
return Object.values(o).filter(function (value) {
if (Array.isArray(value)) {
return value.filter(findValue(str)).length > 0
} else {
return value.toString().includes(str)
}
}).length > 0;
};
};
res = input.filter(findValue("AAS"))
} else {
res = input.filter(function f(o) {
if (o.RazaoSocial.includes("AAS")) return true
if (o.Produtos.length) {
return o.Produtos.filter(function(o1) {
return o1.DescricaoProduto.includes("AAS");
}).length;
}
})
}
console.log(JSON.stringify(res, null, 2));
Upvotes: 2
Reputation: 12035
No recursion needed here. Use a simple filter something like:
var res = input.filter(function (o) {
return o.RazaoSocial.includes("AAS") ||
o.Produtos && o.Produtos.find(function (p) {
return p.DescricaoProduto === 'AAS';
}));
console.log(JSON.stringify(res, null, 2));
At least I think that's what you're after! It should leave you with all the objects in the array where RazaoSocial matches 'AAS' or any of the Produtos have DescriaoProduto == 'AAS'.
Upvotes: 0
Reputation: 547
var res = input.map(function f(o) {
var _ret = false;
if (o.RazaoSocial.includes("AAS")) _ret = true
if (o.Produtos.DescricaoProduto) {
console.log(o.Produtos);
_ret = (o.Produtos = o.Produtos.filter(f)).length
}
return _ret;
})
I haven't test this make use of above
Upvotes: 1