0

I'm trying to implement a search box in which if i start searching for a value it will look for the target in an nested array of objects which is like this:--

[
  {
    "groupId": 1,
    "groupName": "Americas",
    "groupItems": [
      {
        "id": 5,
        "name": "Brazil",
        "parentID": 1,
        "parentName": "Americas"
      },
      {
        "id": 6,
        "name": "Canada",
        "parentID": 1,
        "parentName": "Americas"
      }
    ],
    "isExpanded": false,
    "toggleAllSelection": false
  },
  {
    "groupId": 2,
    "groupName": "APAC",
    "groupItems": [
      {
        "id": 7,
        "name": "Australia",
        "parentID": 2,
        "parentName": "APAC"
      },
      {
        "id": 8,
        "name": "China",
        "parentID": 2,
        "parentName": "APAC"
      }
    ],
    "isExpanded": false,
    "toggleAllSelection": false
  },
  {
    "groupId": 3,
    "groupName": "Europe",
    "groupItems": [
      {
        "id": 9,
        "name": "Belgium",
        "parentID": 3,
        "parentName": "Europe"
      },
{
        "id": 7,
        "name": "Austria",
        "parentID": 2,
        "parentName": "APAC"
      },
      {
        "id": 10,
        "name": "Bulgaria",
        "parentID": 3,
        "parentName": "Europe"
      }
    ],
    "isExpanded": false,
    "toggleAllSelection": false
  }
]

Now i want to search for name property in each groupItems array of objects in group array. and when there is a match my function should return data in same format and as it will be autocomplete so instead of exact match it should be partial match. So if search aus in input box it should return

[{
    "groupId": 2,
    "groupName": "APAC",
    "groupItems": [
      {
        "id": 7,
        "name": "Australia",
        "parentID": 2,
        "parentName": "APAC"
      }],
    "isExpanded": false,
    "toggleAllSelection": false,
},
{
    "groupId": 3,
    "groupName": "Europe",
    "groupItems": [
       {
        "id": 7,
        "name": "Austria",
        "parentID": 2,
        "parentName": "APAC"
      }
    ],
    "isExpanded": false,
    "toggleAllSelection": false
  }

]
user1264429
  • 179
  • 2
  • 11

3 Answers3

0
const findByName = (data, name) => {
  const result = data.reduce((m, { groupItems, ...rest }) => {
    let mapGrpItems = (groupItems || []).filter((item) =>
      item.name.includes(name)
    );
    if (mapGrpItems.length) {
      m.push({ ...rest, groupItems: mapGrpItems });
    }
    return m;
  }, []);
  return result;
};

const findByName = (data, name) => {
  const result = data.reduce((m, { groupItems, ...rest }) => {
    let mapGrpItems = (groupItems || []).filter((item) =>
      item.name.includes(name)
    );
    if (mapGrpItems.length) {
      m.push({ ...rest, groupItems: mapGrpItems });
    }
    return m;
  }, []);
  return result;
};

const data = [{"groupId":1,"groupName":"Americas","groupItems":[{"id":5,"name":"Brazil","parentID":1,"parentName":"Americas"},{"id":6,"name":"Canada","parentID":1,"parentName":"Americas"}],"isExpanded":false,"toggleAllSelection":false},{"groupId":2,"groupName":"APAC","groupItems":[{"id":7,"name":"Australia","parentID":2,"parentName":"APAC"},{"id":8,"name":"China","parentID":2,"parentName":"APAC"}],"isExpanded":false,"toggleAllSelection":false},{"groupId":3,"groupName":"Europe","groupItems":[{"id":9,"name":"Belgium","parentID":3,"parentName":"Europe"},{"id":7,"name":"Austria","parentID":2,"parentName":"APAC"},{"id":10,"name":"Bulgaria","parentID":3,"parentName":"Europe"}],"isExpanded":false,"toggleAllSelection":false}]
console.log(JSON.stringify(findByName(data, "Aus"), null, 2));
xdeepakv
  • 7,835
  • 2
  • 22
  • 32
0

I would definitely attempt to reason through what you're trying to do before just implementing this. Being able to reason through solutions like this is 99% of the job when it comes to programming.

function filterGroups(filter) {
  const result = [];

  myObj.forEach(group => {
    const filteredGroups = group.groupItems.filter(groupItem => {
      return groupItem.name.toLowerCase().includes(filter);
    });

    if (filteredGroups.length > 1) {
      result.push({
        ...group,
        groupItems: filteredGroups
      });
    }
  });

  return result;
}
Josh Gude
  • 210
  • 2
  • 5
0

You can use Arrays.filter for the group items in each outer object in your JSON array to filter out the items which match your search query. You can write something like this:

let autocomplete = (key) => { 
  // arr = Your Data
  let result = []
  arr.forEach(grp=> {
  let out = grp
  let res = grp.groupItems.filter(item => item.name.toLowerCase().includes(key.toLowerCase()))
  if(res.length!=0)
  {
    out.groupItems = res
    result.push(out)}
})
return result
Lavish Jain
  • 148
  • 1
  • 8