mfcss
mfcss

Reputation: 1531

How to filter array of objects in React

I have an array of timeseries objects that I need to filter in React. Specifically, I need to return an array containing a filtered subset of the array of objects, based on the value of device_id being equal to e.g. 7F34B296.

The raw array looks as below:

[
    {
        "label": "time_stamp",
        "data": [
            "2019-04-17 21:01:25.673949957+02:00",
            "2019-04-17 21:01:30.673949957+02:00",
            "2019-04-17 21:01:35.673949957+02:00",
            "2019-04-17 21:01:40.673949957+02:00",
            "2019-04-17 21:01:45.673949957+02:00"
        ]
    },
    {
        "label": "device_id",
        "data": [
            "7F34B296",
            "7F34B296",
            "7F34B296",
            "AB22438D",
            "AB22438D"
        ]
    },
    {
        "label": "parameter_x",
        "data": [
            "929.1965116",
            "927.5152582",
            "928.7476077",
            "1919.2691327",
            "1918.7047619"
        ]
    }
]

The intended output array (after filtering) looks as below:

[
    {
        "label": "time_stamp",
        "data": [
            "2019-04-17 21:01:25.673949957+02:00",
            "2019-04-17 21:01:30.673949957+02:00",
            "2019-04-17 21:01:35.673949957+02:00"
        ]
    },
    {
        "label": "device_id",
        "data": [
            "7F34B296",
            "7F34B296",
            "7F34B296"
        ]
    },
    {
        "label": "parameter_x",
        "data": [
            "929.1965116",
            "927.5152582",
            "928.7476077"
        ]
    }
]

I tried using various methods, including below - but I seem unable to get the desired result. I think I'm missing the part on how to handle that the filtering of the entire array of objects should depend on the value of a subset of one of the objects.

const filters = [
    {
      predicateFn: data => data.data == "7F34B296"
    }
  ];

  function getFilteredPersons(filters) {
    return datasets.filter(p => filters.every(filter => filter.predicateFn(p)));
  }

  console.log(getFilteredPersons(filters));

Upvotes: 1

Views: 14253

Answers (3)

Arvind yadav
Arvind yadav

Reputation: 105

We can use forEach method with splice to get desired output.

let arr = [
    {
        "label": "time_stamp",
        "data": [
            "2019-04-17 21:01:25.673949957+02:00",
            "2019-04-17 21:01:30.673949957+02:00",
            "2019-04-17 21:01:35.673949957+02:00",
            "2019-04-17 21:01:40.673949957+02:00",
            "2019-04-17 21:01:45.673949957+02:00"
        ]
    },
    {
        "label": "device_id",
        "data": [
            "7F34B296",
            "7F34B296",
            "7F34B296",
            "AB22438D",
            "AB22438D"
        ]
    },
    {
        "label": "parameter_x",
        "data": [
            "929.1965116",
            "927.5152582",
            "928.7476077",
            "1919.2691327",
            "1918.7047619"
        ]
    }
]
arr.forEach( (val, index) => val.data.splice(3) ) 
console.log(arr)

Upvotes: -2

zhuber
zhuber

Reputation: 5534

If your data object is always structured same way (3 elements each on same place), then you can do something like this:

const data = [
    {
        "label": "time_stamp",
        "data": [
            "2019-04-17 21:01:25.673949957+02:00",
            "2019-04-17 21:01:30.673949957+02:00",
            "2019-04-17 21:01:35.673949957+02:00",
            "2019-04-17 21:01:40.673949957+02:00",
            "2019-04-17 21:01:45.673949957+02:00"
        ]
    },
    {
        "label": "7F34B296",
        "data": [
            "7F34B296",
            "7F34B296",
            "7F34B296",
            "AB22438D",
            "AB22438D"
        ]
    },
    {
        "label": "parameter_x",
        "data": [
            "929.1965116",
            "927.5152582",
            "928.7476077",
            "1919.2691327",
            "1918.7047619"
        ]
    }
]

const mainData = data[1];
const deviceId = mainData.label;
const indexes = mainData.data.filter((item) => item === deviceId).map((e, idx, array) => idx);
const result = data.map((value) => {
    const filteredData = value.data.filter((item, idx) => {
        return indexes.some((e => idx === e));
    })

    return {
        ...value,
        data: filteredData
    }
});

console.log(result)

Basically just find indexes of device_id in second element of array, and then extract values on those indexes of device_id, time_stamp and parameter_x data properties.

Although this might work, I'd suggest restructuring your data because this is quite complicated structure.

Upvotes: 1

Maciej Trojniarz
Maciej Trojniarz

Reputation: 722

Maybe try to map your data to some kind of the structure f.e.:

const joinedData = []
data.map((element) =>
  element.data.map((e, i) => joinedData[i] = { [element.label]: e, ...joinedData[i]}))

Then you will have transformed data in shape:

 [
      {
        parameter_x: '929.1965116',
        device_id: '7F34B296',
        time_stamp: '2019-04-17 21:01:25.673949957+02:00'
      },
      {
        parameter_x: '927.5152582',
        device_id: '7F34B296',
        time_stamp: '2019-04-17 21:01:30.673949957+02:00'
      },
      {
        parameter_x: '928.7476077',
        device_id: '7F34B296',
        time_stamp: '2019-04-17 21:01:35.673949957+02:00'
      },
      {
        parameter_x: '1919.2691327',
        device_id: 'AB22438D',
        time_stamp: '2019-04-17 21:01:40.673949957+02:00'
      },
      {
        parameter_x: '1918.7047619',
        device_id: 'AB22438D',
        time_stamp: '2019-04-17 21:01:45.673949957+02:00'
      }
    ]

which will be easier to filter

Upvotes: 2

Related Questions