最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to filter array of objects in React - Stack Overflow

programmeradmin3浏览0评论

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));

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));
Share Improve this question asked Sep 16, 2019 at 9:28 mfcssmfcss 1,5512 gold badges14 silver badges37 bronze badges 6
  • so each array in the object are in the same sorted order? – arizafar Commented Sep 16, 2019 at 9:31
  • Yes, that is correct. The raw data es from an SQL query based on a simple CSV database. To avoid having to call the SQL query for each device_id, I instead include the device_id as a column in the query output and aim to filter the data once fetched to split it by device_id. I've not found other posts where the filtering of the entire array has to be done based on the object data of one of the arrays. – mfcss Commented Sep 16, 2019 at 9:35
  • It won't work with filter by itself, you need to map the object - adding an id to each entry, then filter by it, eventually mapping and removing the id added – Dennis Vash Commented Sep 16, 2019 at 9:39
  • Or doing it in a nested loop which will be unreadable. – Dennis Vash Commented Sep 16, 2019 at 9:40
  • Is device_id always at index 1 of array? – zhuber Commented Sep 16, 2019 at 9:42
 |  Show 1 more ment

3 Answers 3

Reset to default 2

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

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 plicated structure.

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)
发布评论

评论列表(0)

  1. 暂无评论