Search code examples
javascriptarraysobjectfilterflatmap

Find the search keyword in nesting array of objects


 let arr = [
      {
        id:{key:1, name:"apple"},
        fruits:[{id:{key:1.1,name:"green apple"}},{id:{key:1.2, name: "red apple"}}]
      },
      {
        id:{key:2, name:"grapes"},
        fruits:[{id:{key:2.1,name:"green grapes"}},{id:{key:2.2, name: "black grapes"}}]
      },
      {
        id:{key:3, name:"berries"},
        fruits:[{id:{key:3.1,name:"strawberries"}},{id:{key:3.2, name: "blueberries"}}]
      },
      {
        id:{key:4, name:"banana"},
        fruits:[{id:{key:4.1,name:"yellow banana"}}]
      }
    ]

const search = "pp"

    function filterResult(obj) {
      const re = new RegExp(search, "ig")
      return re.test(obj.id.name)
    }

    //this gives result of outer id array only 
   const searchResult = [
...Object.values(arr).filter((v) => {  
     let tempArr = [];
      if (filterResult(v)) {
        tempArr.push(v);
         return [...tempArr,...(v.fruits).filter((vv) => {
            return filterResult(vv);
          })]    
      }
    })
].map((res)=>res.id);

console.log(searchResult);

But now how to search in nested array (fruits) of arr I tried to use flatMap, but I feel i did something wrong.

const searchResult = [
...Object.values(arr).filter((v) => {  
     let tempArr = [];
      if (filterResult(v)) {
        tempArr.push(v);
         return [...tempArr,...(v.fruits).filter((vv) => {
             filterResult(vv);
          })]    
      }
    })
]

I want "search Result" result like : because they pp keyword in all ( parent + child on same level)

[{id:1, name: "apple"}, {id:1.1,name:"green apple"},{id:1.2, name: "red apple"}]

PS: not allowed to use flatMap


Solution

  • Solution

    /**
     * Sample data provided.
     */
    const arr = [
      {
        id: { id: 1, name: 'apple' },
        fruits: [{ id: 1.1, name: 'green apple' }, { id: 1.2, name: 'red apple' }]
      },
      {
        id: { id: 2, name: 'grapes' },
        fruits: [{ id: 2.1, name: 'green grapes' }, { id: 2.2, name: 'black grapes' }]
      },
      {
        id: { id: 3, name: 'berries' },
        fruits: [{ id: 3.1, name: 'strawberries' }, { id: 3.2, name: 'blueberries' }]
      },
      {
        id: { id: 4, name: 'banana' },
        fruits: [{ id: 4.1, name: 'yellow banana' }]
      }
    ];
    
    /**
     * Find all fruits whose name contains the query.
     *
     * @param {*} array items to iterate through
     * @param {*} query search query
     * @returns {Array} array of objects whose property name contains the query
     */
    const search = (array, query) => {
      /**
       * MDN documentation on Array.prototype.reduce
       * ------------------------------------------------------
       * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
       * ------------------------------------------------------
       */
      return array.reduce((acc, item) => {
        return [
          ...acc,
          /**
           * Add the item to the accumulator if the item name contains the query.
           */
          ...item.id.name.includes(query) ? [item.id] : [],
          /**
           * Add all fruits whose name contains the query to the accumulator.
           */
          ...item.fruits.filter(fruit => fruit.name.includes(query))]
      }, []);
    };
    
    console.log(search(arr, 'pp'));
    

    Output

    [
      { id: 1, name: 'apple' },
      { id: 1.1, name: 'green apple' },
      { id: 1.2, name: 'red apple' }
    ]