【问题标题】:how to loop through data and assign values to state array in react如何在反应中循环数据并将值分配给状态数组
【发布时间】:2019-05-23 06:12:14
【问题描述】:

我有一个类组件,它的状态包含一个 filterItems[] 空白数组。我需要填充 filterItems 数组中的值

所以,我有一个来自 API 的数据,看起来像这样:

0:
emp_code: "a001"
company_code: "company_a"
keys: ["id", "post" ] 
dtypes: ["str", "int"]

1:
emp_code: "b001"
company_code: "company_b"
keys: ["sal", "name" ] 
dtypes: ["int", "str"]

//so on for other companies and employees

所以,像这样,我有几个员工。 现在我必须遍历这个 api 数据并提取信息并将其存储到另一个名为“filters”的数组中并将其传递给一个函数。

我的过滤器数组应该是这样的:

filters: [
        {
          key_name: "id",
          company_code: "company_a",
          input_type: "text",
          dtype: "str"
        },
        {
          key_name: "post",
          company_code: "company_a",
          input_type: "text",
          dtype: "int"
        },
//... keys for other company
]

基本上, 我需要在反应中做以下事情

for each emp_code
  for each company_code
     for each key:
         keys[i]== filters.key_name
         company_code== filters.company_code
//...so on

这里的问题是,每家公司都有一组键,所以如果员工属于同一家公司,那么我不需要再次添加到过滤器数组中。 所以,我基本上需要检查唯一的 company_code 并将公司拥有的不同类型的键添加到过滤器数组中。

【问题讨论】:

  • 为什么不添加来自 api 的数据,而不是控制台日志?
  • 是你正在努力解决的算法还是在 React 中的哪里做它才有意义?如果您使用 16.6 的响应,我认为 getDerivedStateFromProps 可能是放置映射的合适位置

标签: javascript reactjs


【解决方案1】:

如果我的理解正确,您希望像这样过滤您的数据:

假设您将 API 数据存储在一个名为 myArr 的变量中

创建一个名为 updatedArr 的新变量,它将映射到 myArr

const updatedArr = myArr.map((company, compIndex, compArr) => {
    return company.keys.map((key, keyIndex, keyArr) => {
        return {
            key_name: key,
            company_code: company.company_code,
            input_type: "text",
            dtype: company.dtypes[keyIndex]
        }
    })
}).reduce((acc, cur) => {
    return [...acc, ...cur]
}, [])

然后解析 updatedArr 以仅获取 uniqueValues

let uniqueValues = [];
//parses out duplicates
updatedArr.forEach(function(item) {
  //i will be 0 or more if there already is an item in our array, which means the current item we are iterating over is a duplicate
  var i = uniqueValues.findIndex(
    x => x.dtype == item.dtype && x.company_code == item.company_code
  );
  if (i <= -1) {
    //if item is not yet inside uniqueValues, add it to uniueValues
    uniqueValues.push(item);
  }
});

然后使用 uniqueValues 更新您的 componentState

this.setState({
   filters: uniqueValues
})

还创建了一个沙盒来向您展示这个正在运行的工作: https://codesandbox.io/s/rendering-companies-ibs7g

【讨论】:

  • 这工作正确,你能不能也展示如何检查公司的唯一性。所以基本上如果公司已经存在,我不希望它再次添加公司。
  • @user8306074 噢噢噢。所以你只想让公司添加一次,那么你如何处理不同的键和数据类型呢?他们不需要自己的物品吗?您向我们展示的所需输出具有多个相同的 company_code,因此不清楚您要做什么:/
  • 所以基本上,我想根据键对每个 company_code 应用过滤器。所以键是我数据集中的列,它们是公司的关键标识符。所以我想根据 company_code 应用任何过滤并检索这些过滤器的 emp_code。您的代码运行良好。但它为每一行生成一个输出。因此,如果我有同一家公司的两名员工,那么它将在过滤器数组中创建两个相同的对象。因此,我希望 company_code 是 unqiue
  • 所以,如果我的数组再次读取相同的 company_code,则拒绝它,然后移至下一行。我想我们需要一个 if 条件来在第一个 map 循环之后检查它
  • 嗯,这是一个可能的解决方案。现在我们为公司中的每个唯一键生成一个对象,我认为这对于您希望如何使用这些数据是有意义的。我认为我们实际上需要配置您的表代码,以便它知道如何正确过滤这些数据。不过,这可能完全是一个单独的问题。
【解决方案2】:

假设你的数据是一个数组。

    let filters = [];

    data.forEach(item => {
        item.keys.forEach(key => {
            item.dtypes.forEach(dtype => {
                const filter = {
                    key_name: key,
                    company_code: item.company_code,
                    input_type: "text",
                    dtype: dtype
                };
                filters.push(filter)
            })
        })
    });

【讨论】:

  • 所以这将遍历每个键并为不同的 dtype 生成两个输出,但在我的状态下:key id 有一个 dtype str,post 有一个 dtype 作为 int。所以我需要同时遍历键和数据类型
  • 是的。它是在上面的sn-p中完成的。首先循环outerLoop上的所有项目。然后循环所有键,循环 innerLoop 中的所有 dtypes 并创建新对象并将其推送到过滤器。试试这个 sn-p,让我知道你的想法
猜你喜欢
  • 1970-01-01
  • 2015-07-16
  • 1970-01-01
  • 2019-07-22
  • 2021-05-14
  • 2023-03-23
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
相关资源
最近更新 更多