ST80
ST80

Reputation: 3893

Javascript How to filter through nested array data

I have a search field which filters through an array when I'm typing. So far it works ok, but I cannot search within the "courses" array! How can I achieve this? The complete array looks like this:

const data = [{
  name: "john doe",
  city: "blabla",
  zipcode: "1234",
  email: "[email protected]",
  phone: "12345678",
  courses: [
   {
     title: "some course",
     provider: "some provider",
     end_date: "some date"
    },
   {
     title: "another course",
     provider: "another provider",
     end_date: "another date"
    },
  ]
]

Here is my JS code so far, where I can search through all fields, except the "courses"-array:

data = data.filter(row => {
   return Object.keys(row).some(key => {
     return (
       String(row[key])
        .toLowerCase()
        .indexOf(filter) > -1
      );
   });
});

Can someone help me out?

Upvotes: 2

Views: 75

Answers (2)

Carsten Massmann
Carsten Massmann

Reputation: 28196

The following will search both, all fields of your top level objects in dataas well as all fields in the objects of each course array:

const data = [{
  name: "john doe",
  city: "blabla",
  zipcode: "1234",
  email: "[email protected]",
  phone: "12345678",
  courses: [
   {
     title: "some course",
     provider: "some provider",
     end_date: "some date"
    },
   {
     title: "another course",
     provider: "another provider",
     end_date: "another date"
    },
  ]},
{
  name: "jane aire",
  city: "dooodaaah",
  zipcode: "987",
  email: "[email protected]",
  phone: "8997652",
  courses: [
   {
     title: "how to win",
     provider: "by herself",
     end_date: "tomorrow"
    },
   {
     title: "you can do it",
     provider: "Harry",
     end_date: "next week"
    },
  ]}
];

// check whether `filter` is found in `value`:
function chk(filter){return function(value){return String(value).toLowerCase().indexOf(filter)>-1}}
const res=document.getElementById('res');  // show found results in <pre id="res">

// whenever the input changes:
document.querySelector('input').oninput=ev=>{
 let chkfilt=chk(ev.target.value || null);
 res.innerHTML=JSON.stringify(
   data.filter(row => { return Object.values(row).some(chkfilt) 
                               || row.courses.some(o=>Object.values(o).some(chkfilt)) })
   ,null,2);
}
.as-console-wrapper {max-height:100% !important}
<input type="text" placeholder="search string ...">

<pre id="res"></pre>

Upvotes: 1

hgb123
hgb123

Reputation: 14871

Below snippet could help you

const data = [
  {
    name: "john doe",
    city: "blabla",
    zipcode: "1234",
    email: "[email protected]",
    phone: "12345678",
    courses: [
      {
        title: "some course",
        provider: "some provider",
        end_date: "some date",
      },
      {
        title: "another course",
        provider: "another provider",
        end_date: "another date",
      },
    ],
  },
]

const courseTitle = "another"

const res = data.filter(
  (el) =>
    el.courses.find((course) =>
      course.title.toLowerCase().includes(courseTitle.toLowerCase())
    ) !== undefined
)

console.log(res)

Upvotes: 0

Related Questions