Home > Software engineering >  Filter array of objects with valid data
Filter array of objects with valid data

Time:11-27

I have an array that contains key and value like,

  const array = [
    {
      DEVICE_SIZE: ['036', '048', '060', '070'],
    },
    {
      DEVICE_VOLTAGE: ['1', '3'],
    },
    {
      'NOT DEVICE_DISCHARGE_AIR': ['S'],
    },
    {
      'NOT DEVICE_REFRIGERANT_CIRCUIT': ['H', 'C'],
    },
  ];

The key here is going to play a major role for the result because of its NOT keyword.

And I have original array of objects for each key like the following data,

  const data = {

    DEVICE_SIZE: [
      { id: 20, name: 'Size 20' },
      { id: 36, name: 'Size 36' },
      { id: 40, name: 'Size 40' },
      { id: 20, name: 'Size 48' },
      { id: 60, name: 'Size 60' },
      { id: 70, name: 'Size 70' },
    ],

    DEVICE_VOLTAGE: [
      { id: 1, name: 'Voltage 1' },
      { id: 2, name: 'Voltage 2' },
      { id: 3, name: 'Voltage 3' },
      { id: 4, name: 'Voltage 4' },
      { id: 5, name: 'Voltage 5' },
    ],

    DEVICE_DISCHARGE_AIR: [
      { id: 'E', name: 'Discharge E' },
      { id: 'S', name: 'Discharge S' },
      { id: 'T', name: 'Discharge T' },
    ],

    DEVICE_REFRIGERANT_CIRCUIT: [
      { id: 'C', name: 'Refrigerant C' },
      { id: 'E', name: 'Refrigerant E' },
      { id: 'H', name: 'Refrigerant H' },
      { id: 'M', name: 'Refrigerant M' },
    ],

  };

Requirement in detail:

Here for first two values DEVICE_SIZE and DEVICE_VOLTAGE it is positive case whereas for 'NOT DEVICE_DISCHARGE_AIR' and 'NOT DEVICE_REFRIGERANT_CIRCUIT' it has the keyword of NOT.

I need to filter all the above given array's and combine positive and negative result like,

Without NOT in the key:

For eg.., DEVICE_SIZE: ['036', '048', '060', '070'] which is positive (without NOT keyword), so I need to get valid id's under DEVICE_SIZE which is DEVICE_SIZE: [36, 48, 60, 70]

With NOT in the key:

For eg.., 'NOT DEVICE_DISCHARGE_AIR': ['S'] which is negative , so I need to get valid id's other than value S under DEVICE_DISCHARGE_AIR which is ["E", "T"]

If there is a NOT keyword in the object, then while mapping with the respective array of objects, I need to ignore the particular value and give other results.

Expected Output:

The final expected valid object would be,

const valid = {
  DEVICE_SIZE: [36, 48, 60, 70],
  DEVICE_VOLTAGE: [1, 3],
  DEVICE_DISCHARGE: ["E", "T"],
  DEVICE_REFRIGERANT_CIRCUIT: ["E", "M"],
};

CodePudding user response:

You could convert the array to a list of key/value pairs, flatten it, and then use a regex to extract the optional "NOT" prefix from it. Then you are left with a key in either case. With this key look up the corresponding IDs from the data array. If a "NOT" was found, filter those data IDs so those that are given in the array are excluded:

const filter = (data, filters) =>
    Object.fromEntries(
        filters.flatMap(Object.entries).map(([action, ids]) => {
            let [, not, key] = action.match(/(NOT )?(.*)/);
            let allids = data[key].map(({id}) => id);
            if (typeof allids[0] == "number") ids = ids.map(Number);
            if (not) {
                ids = new Set(ids);
                return [key, allids.filter(id => !ids.has(id))];
            }
            return [key, ids];
        })
    );

// Your example inputs:
const array = [{DEVICE_SIZE: ['036', '048', '060', '070'],},{DEVICE_VOLTAGE: ['1', '3'],},{'NOT DEVICE_DISCHARGE_AIR': ['S'],},{'NOT DEVICE_REFRIGERANT_CIRCUIT': ['H', 'C'],},];
const data = {DEVICE_SIZE: [{ id: 20, name: 'Size 20' },{ id: 36, name: 'Size 36' },{ id: 40, name: 'Size 40' },{ id: 20, name: 'Size 48' },{ id: 60, name: 'Size 60' },{ id: 70, name: 'Size 70' },],DEVICE_VOLTAGE: [{ id: 1, name: 'Voltage 1' },{ id: 2, name: 'Voltage 2' },{ id: 3, name: 'Voltage 3' },{ id: 4, name: 'Voltage 4' },{ id: 5, name: 'Voltage 5' },],DEVICE_DISCHARGE_AIR: [{ id: 'E', name: 'Discharge E' },{ id: 'S', name: 'Discharge S' },{ id: 'T', name: 'Discharge T' },],DEVICE_REFRIGERANT_CIRCUIT: [{ id: 'C', name: 'Refrigerant C' },{ id: 'E', name: 'Refrigerant E' },{ id: 'H', name: 'Refrigerant H' },{ id: 'M', name: 'Refrigerant M' },],};

const result = filter(data, array);
console.log(result);

  • Related