【问题标题】:How to filter array of objects in React如何在 React 中过滤对象数组
【发布时间】:2020-01-17 02:52:58
【问题描述】:

我有一组时间序列对象,需要在 React 中过滤。 具体来说,我需要返回一个包含对象数组的过滤子集的数组,基于device_id 的值等于例如7F34B296.

原始数组如下所示:

[
    {
        "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"
        ]
    }
]

预期的输出数组(过滤后)如下所示:

[
    {
        "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"
        ]
    }
]

我尝试使用各种方法,包括以下方法 - 但我似乎无法获得所需的结果。我想我错过了关于如何处理整个对象数组的过滤应该取决于其中一个对象的子集的值的部分。

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

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

  console.log(getFilteredPersons(filters));

【问题讨论】:

  • 那么对象中的每个数组的排序顺序是一样的吗?
  • 是的,没错。原始数据来自基于简单 CSV 数据库的 SQL 查询。为了避免必须为每个 device_id 调用 SQL 查询,我将 device_id 作为列包含在查询输出中,并旨在过滤获取的数据以将其拆分为 device_id。我还没有找到其他必须根据其中一个数组的对象数据过滤整个数组的帖子。
  • 它本身不适用于filter,你需要map对象-在每个条目中添加id,然后filter,最终mapping并删除添加的id
  • 或者在一个不可读的嵌套循环中进行。
  • device_id 总是在数组的索引 1 处吗?

标签: javascript arrays reactjs filter


【解决方案1】:

也许尝试将您的数据映射到某种结构 f.e.:

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

然后你将有形状转换的数据:

 [
      {
        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'
      }
    ]

这样会更容易过滤

【讨论】:

  • 这对我也有很大帮助,实际上我最终也使用了它,因为我需要更改数据的输出结构。谢谢!
【解决方案2】:

如果您的数据对象始终以相同的方式构造(3 个元素在同一个位置),那么您可以执行以下操作:

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)

基本上只是在数组的第二个元素中找到device_id 的索引,然后在device_idtime_stampparameter_xdata 属性的这些索引上提取值。

虽然这可能可行,但我建议重组您的数据,因为这是一个相当复杂的结构。

【讨论】:

  • 这个结果提供了我正在寻找的东西,谢谢!小编辑:在我的例子中,deviceId 在标签中没有找到,因为它被简单地命名为device_id。但是通过将 deviceId 变量设置为等于例如7F34B296我得到过滤结果。这让我可以拆分数据。
【解决方案3】:
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)

【讨论】:

    猜你喜欢
    • 2020-09-25
    • 2021-04-23
    • 2022-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    相关资源
    最近更新 更多