Home > Mobile >  Filter multiples search values with a nested array
Filter multiples search values with a nested array

Time:08-13

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 => {
        return item.cities.filter((city, i) => {
          return Object.keys(this.filterParams).some(key => {
            return data.cities[i][key].toString().toLowerCase().includes(value);
          })
    })

CodePudding user response:

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"
    }
]
*/

CodePudding user response:

This return the item (array) that approved the validation

const data = [ // initial data
  {
    cities: [
      { name: "fo", federatedUnit: "SP" },
      { name: "BOITUVA", federatedUnit: "SP" },
      { name: "PORTO FELIZ", federatedUnit: "SP" }
    ],
    code: "202",
    description: "someDescription",
    id: "1",
    minimumWeight: 30,
    operationDays: {
      monday: false,
      tuesday: false,
      wednesday: false,
      thursday: false,
      friday: true
    },
    tax: "ICMS"
  },
  {
    cities: [
      { name: "TATUÍ", federatedUnit: "SP" },
      { name: "BOITUVA", federatedUnit: "SP" },
      { name: "PORTO FELIZ", federatedUnit: "SP" }
    ],
    code: "400",
    description: "someDescription",
    id: "2",
    minimumWeight: 60,
    operationDays: {
      monday: false,
      tuesday: false,
      wednesday: false,
      thursday: false,
      friday: true
    },
    tax: "ICMS2"
  }
];

// filter
data.forEach((item) => {
  // filter by code and minWeight
  if (item.code === "202" && item.minimumWeight === 30){
    // fulter by city name
    item.cities.forEach((city) => {
      if (city.name === "fo"){
        return console.log(item) // return the item
      }
    })
  }
})
  • Related