Vdas Dorls
Vdas Dorls

Reputation: 495

Javascript filter two arrays

So I would need to filter array and an array within this array.

So, we have an array -

arr: [
   {
      name: 'object',
      array2: [
         {
            name: '1'
         },
         {
            name: '2'
         }
      ]
   },
   {
      name: 'object 2',
      array2: [
         {
            name: 'object'
         }
      ]
   }
]

I enter a value 2 in the filter, and the output, that I would like to have here is -

arr: [
   {
      name: 'object',
      array2: [
         {
            name: '2'
         }
      ]
   },
   {
      name: 'object 2',
      array2: []
   }
]

I have the matching logic here, and it works on the outer level (the first level, where I have an object with name and array2 parameters). The inner level also works, but the issue here is that, if I filter the inner level, I'm not able to get back the initial state of the inner objet, that is. I have an input bar, if I enter 2, it's filtered just fine, but, if I remove 2, then it shows other elements from arr: [], but doesn't show filtered elements from array2: [].

Any ideas on how to fix this?

Link to jsFiddle with comments - http://jsbin.com/pupugoxebi/edit?html,js,output .

I coudl manually push in the new array, but this doesn't work because I have dynamic array, for example, it can have different properties, and writing manually won't solve it. Updated version - http://jsbin.com/bifolisefu/edit?html,js,output .

Upvotes: 0

Views: 1016

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386680

You could use either the ceck for the name of the outer array or check if the inner array returns some items, then build a new object and concat it to the result set.

function getNodes(array, name) {
    return array.reduce(function (r, a) {
        var temp = a.array2.filter(b => b.name.includes(name));
        return r.concat(
            a.name.includes(name) || temp.length ?
            Object.assign({}, a,  { array2: temp }) :
            []
        );
    }, []);
}

var array = [{ name: 'test', foo: 0, array2: [{ name: 'test 2', foo: 1 }, { name: 'test 3', foo: 2 }] }, { name: 'test 2', foo: 3, array2: [{ name: 'test', foo: 4 }] }, { name: 'test 3', foo: 5, array2: [{ name: 'test 4', foo: 6 }, { name: 'test 5', foo: 7 }] }];

console.log(getNodes(array, '2'));
console.log(getNodes(array, '3'));
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Mμ.
Mμ.

Reputation: 8542

Try the following code.

var arr2 = [
  {
    name: 'test',
    array2: [
      {
        name: 'test 2'
      },
      {
        name: 'test 3'
      }
    ]
  },
  {
    name: 'test 2',
    array2: [
      {
        name: 'test'
      }
    ]
  },
  {
    name: 'test 3',
    array2: [
      {
        name: 'test 4'
      },
      {
        name: 'test 5'
      }
    ]
  }
];

arr2.map(e => {
  var tmp = e.array2.filter(e2 => e2.name.includes('2'));
  e.array2 = tmp;
});

console.log(arr2);

Upvotes: 0

Related Questions