简体   繁体   中英

Object inside array inside object inside array JavaScript - Search

I have a data like this:

 const bigData = [ { id: '1', data: [ {category: 'swim', value: 'Abc'}, {category: 'ran', value: '123'}, {category: 'play', value: 'Test'} ] }, { id: '2', data: [ {category: 'swim', value: 'Abc'}, {category: 'ran', value: ''}, {category: 'play', value: 'abc'} ] }, { id: '3', data: [ {category: 'swim', value: 'String that I Need'}, {category: 'ran', value: '456'}, {category: 'play', value: 'Testtest'} ] } ]

I want to get array of objects if one of this objects contains part of the string in their value.

For example, if the search string is "String tha" it should return

   [ {
    id: '3',
    data: [
      {category: 'swim', value: 'String that I Need'},
      {category: 'ran', value: '456'},
      {category: 'play', value: 'Testtest'}
    ]
  }]

And if the search string is "Abc" it should return

[{
        id: '1',
        data: [
          {category: 'swim', value: 'Abc'},
          {category: 'ran', value: '123'},
          {category: 'play', value: 'Test'}
        ]
      },
      {
        id: '2',
        data: [
          {category: 'swim', value: 'somethinf'},
          {category: 'ran', value: ''},
          {category: 'play', value: 'Abcd'}
        ]
      },]

This is what I have so far, not sure if it is even the right direction to go:

const arr = bigData.map(
      (item) => item.data
    )
    const res = arr
      ?.map((item) => item.map((e) => e.value))
      .filter((i) => i.map((e) => e.includes(search) === true))

There's no reason to map() the outer array to each object's data member, since the return value and the input value have the same layout. Instead, you're performing a filter() on the outer array bigData , which should keep objects whose inner array member data satisfies a certain condition.

You can check for that condition using some() , since it is applied to each element of the array, and you only care whether or not there exists an element that matches.

 function filterBySearch (search) { return bigData.filter( ({ data }) => data.some( ({ value }) => value.includes(search) ) ); } const bigData = [ { id: '1', data: [ {category: 'swim', value: 'Abc'}, {category: 'ran', value: '123'}, {category: 'play', value: 'Test'} ] }, { id: '2', data: [ {category: 'swim', value: 'Abc'}, {category: 'ran', value: ''}, {category: 'play', value: 'abc'} ] }, { id: '3', data: [ {category: 'swim', value: 'String that I Need'}, {category: 'ran', value: '456'}, {category: 'play', value: 'Testtest'} ] } ]; console.log(filterBySearch('String tha')); console.log(filterBySearch('Abc'));
 .as-console-wrapper{max-height:100%!important;}

The easiest approach is the one liner already provided by Patrick. You are on the right path, but just getting tripped up on the proper use of the array functions. If you wanted to write this as a function, it would look like:

function searchBigData(bigData, searchText) {
    return bigData.filter(entry => entry.data.some(item => item.value.includes(searchText)));
}

For future reference, the basic strategy here is:

  1. Use filter on the bigData array because you want to reduce that down to the original objects that meet your criteria.
  2. For each item in bigData, use some against the data array. It will return true as soon as one of the items in data matches the condition.
  3. Test each item in data for the value to include the search text

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM