Daniel Nunes
Daniel Nunes

Reputation: 1

Filter multiples search values with a nested array

I have an Array of objects like this:

data = [{
 cities: [
   {name: 'TATUÍ', federatedUnit: 'SP'},
   {name: 'BOITUVA', federatedUnit: 'SP'},
   {name: 'PORTO FELIZ', federatedUnit: 'SP'}
  ]
 code: "someCode"
 description: "someDescription"
 id: "someId"
 minimumWeight: 60
 operationDays: {monday: false, tuesday: false, wednesday: false, thursday: false, friday: true}
 tax: "ICMS"
}]

And i have multiples search fields for: code, city name, federatedUnit, minimumWeight

I want to be able to search for example:

{code: '202', cities: {name: 'bo'}, minimumWeight: 30}

I already know how to build the 'search object' like the example above that i named filterParams.

The problem is, i dont know how to filter for multiple values and with the nested 'cities' array of objects.

My code is something like this:

    this.filteredData = this.data.filter(item => {
      if(this.isCitiesSearch) {
        return item.cities.filter((city, i) => {
          return Object.keys(this.filtersParams).some(key => {
            if(city[key].toString().toLowerCase().includes(value)) {
              return item;
            }
          })
        })
      } else {
        return Object.keys(this.filtersParams).some(key => {
          return item[key].toString().toLowerCase().includes(value);
        })
      }
    })

Upvotes: 0

Views: 68

Answers (1)

Kostanos
Kostanos

Reputation: 10404

Here is one of the solutions taking in consideration your input.

But I would recommend you to change the parameters that you send to the filter. Instead of city: {name:'..'} just send cityName: '...'.

Also, I'm not quite sure if the search should be inclusive or exclusive. In my example it is exclusive. Which means, if, at least one parameter will not match, the item will be excluded.

/**
 * @param {Object} param
 * @param {String} param.code
 * @param {Object} param.city
 * @param {String} param.city.name
 * @param {Number} param.minimumWeight
 */
function findLocation({ code, city, minimumWeight }) {
  return data.filter((item) => {
    if (code) {
      if (!item.code.toLocaleLowerCase().includes(code.toLocaleLowerCase())) return false;
    }
    if (city) {
      if (!item.cities.find((ct) => ct.name.toLocaleLowerCase().includes(city.name.toLocaleLowerCase()))) return false;
    }
    if (minimumWeight !== undefined) {
      if (item.minimumWeight !== minimumWeight) return false;
    }
    return true;
  });
}

Tests:

const data = [{
  cities: [
    { name: 'TATUÍ', federatedUnit: 'SP' },
    { name: 'BOITUVA', federatedUnit: 'SP' },
    { name: 'PORTO FELIZ', federatedUnit: 'SP' },
  ],
  code: 'someCode',
  description: 'someDescription',
  id: 'someId',
  minimumWeight: 60,
  operationDays: { monday: false, tuesday: false, wednesday: false, thursday: false, friday: true },
  tax: 'ICMS',
}, {
  cities: [
    { name: 'MALAGA', federatedUnit: 'SP' },
    { name: 'MADRID', federatedUnit: 'SP' },
    { name: 'BARCELONA', federatedUnit: 'SP' },
  ],
  code: 'anotherCode',
  description: 'anotherDescription',
  id: 'anotherId',
  minimumWeight: 80,
  operationDays: { monday: false, tuesday: false, wednesday: false, thursday: false, friday: true },
  tax: 'ICMS',
},
];

findLocation({ city: { name: 'mad' } });
/*
[
    {
        "cities": [
            {
                "name": "MALAGA",
                "federatedUnit": "SP"
            },
            {
                "name": "MADRID",
                "federatedUnit": "SP"
            },
            {
                "name": "BARCELONA",
                "federatedUnit": "SP"
            }
        ],
        "code": "anotherCode",
        "description": "anotherDescription",
        "id": "anotherId",
        "minimumWeight": 80,
        "operationDays": {
            "monday": false,
            "tuesday": false,
            "wednesday": false,
            "thursday": false,
            "friday": true
        },
        "tax": "ICMS"
    }
]
*/

findLocation({ code: 'some', city: { name: 'tat' } });
/*
[
    {
        "cities": [
            {
                "name": "TATUÍ",
                "federatedUnit": "SP"
            },
            {
                "name": "BOITUVA",
                "federatedUnit": "SP"
            },
            {
                "name": "PORTO FELIZ",
                "federatedUnit": "SP"
            }
        ],
        "code": "someCode",
        "description": "someDescription",
        "id": "someId",
        "minimumWeight": 60,
        "operationDays": {
            "monday": false,
            "tuesday": false,
            "wednesday": false,
            "thursday": false,
            "friday": true
        },
        "tax": "ICMS"
    }
]
*/

Upvotes: 1

Related Questions