0

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.

3 Answers3

2

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));
gotomanners
  • 7,808
  • 1
  • 24
  • 39
1
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

0

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'.

see sharper
  • 11,505
  • 8
  • 46
  • 65