将数据数组转换为 SectionList 组件的分组数据

Posted

技术标签:

【中文标题】将数据数组转换为 SectionList 组件的分组数据【英文标题】:Transform array of data into grouped data for SectionList component 【发布时间】:2021-11-18 12:11:23 【问题描述】:

我承认 javascript 不是我最擅长的语言,而且 React Native 是非常新的,所以,可能有一种我没有看到的明显简单的方法。

我有一个以简单结构呈现一些交易数据的 API:

[
  
    "id": 1,
    "title": "Apple Store",
    "date": "2021-09-10",
    "amount": "$100.00",
  ,
  
    "id": 41,
    "title": "Zulauf, Walter and Metz",
    "date": "2021-09-10",
    "amount": "$14.00",
  ,
  
    "id": 9,
    "title": "Aufderhar PLC",
    "date": "2021-09-09",
    "amount": "$78.00",
  ,
  
    "id": 10,
    "title": "Bayer and Sons",
    "date": "2021-09-07",
    "amount": "$67.00",
  
]

我想使用 SectionList 组件来呈现这些数据,其中交易按日期划分。我(可能是粗略的)解决这个问题的尝试是将这些数据转换为以下结构:

[
  
    "date": "2021-09-10",
    "transactions": [
      
        "id": 1,
        "title": "Apple Store",
        "date": "2021-09-10",
        "amount": "$100.00",
      ,
      
        "id": 41,
        "title": "Zulauf, Walter and Metz",
        "date": "2021-09-10",
        "amount": "$14.00",
      
    ]
  ,
  
    "date": "2021-09-09",
    "transactions": [
      
        "id": 9,
        "title": "Aufderhar PLC",
        "date": "2021-09-09",
        "amount": "$78.00",
      
    ]
  ,
  
    "date": "2021-09-07",
    "transactions": [
      
        "id": 10,
        "title": "Bayer and Sons",
        "date": "2021-09-07",
        "amount": "$67.00",
      
    ]
  
]

但老实说,我不知道如何转换这些数据(或者是否有更好的方法来解决这个问题)。我从使用 Lodash 的 groupBy 函数开始,这看起来很有希望,但看起来 SectionList 不想要一个对象,它想要一个数组。

将 groupBy 的输出直接转换为数组会丢弃键,我已经得到分组数据,但节标题没有明确的值。

同样,可能有一些非常简单的方法可以解决这个问题,数据始终以平面数组的形式出现。我感谢任何人可以指出我的任何指导、帮助或示例。

【问题讨论】:

这能回答你的问题吗? Group a Javascript Array 【参考方案1】:

const input = [
  
    "id": 1,
    "title": "Apple Store",
    "date": "2021-09-10",
    "amount": "$100.00",
  ,
  
    "id": 41,
    "title": "Zulauf, Walter and Metz",
    "date": "2021-09-10",
    "amount": "$14.00",
  ,
  
    "id": 9,
    "title": "Aufderhar PLC",
    "date": "2021-09-09",
    "amount": "$78.00",
  ,
  
    "id": 10,
    "title": "Bayer and Sons",
    "date": "2021-09-07",
    "amount": "$67.00",
  
]

const result = input.reduce((accum, current)=> 
  let dateGroup = accum.find(x => x.date === current.date);
  if(!dateGroup) 
    dateGroup =  date: current.date, transactions: [] 
    accum.push(dateGroup);
  
  dateGroup.transactions.push(current);
  return accum;
, []);

console.log(result)

给定一个数组,只要您的结果期望具有相同数量的元素,请使用map,但由于您的结果具有不同数量的元素,请使用reduce,如上所示。这个想法是通过reduce,循环遍历每个元素,看看是否可以找到元素,然后将当前元素推入列表中

【讨论】:

完美,我特别喜欢它与本机功能一起使用。谢谢!【参考方案2】:

lodash groupBy 只是帮助您处理分组数据,您应该通过将分组数据转换为您的格式来处理分组数据。

const input = [
  
    "id": 1,
    "title": "Apple Store",
    "date": "2021-09-10",
    "amount": "$100.00",
  ,
  
    "id": 41,
    "title": "Zulauf, Walter and Metz",
    "date": "2021-09-10",
    "amount": "$14.00",
  ,
  
    "id": 9,
    "title": "Aufderhar PLC",
    "date": "2021-09-09",
    "amount": "$78.00",
  ,
  
    "id": 10,
    "title": "Bayer and Sons",
    "date": "2021-09-07",
    "amount": "$67.00",
  
];

const groupedArray = _.groupBy(input, "date");

let result = [];
for (const [key, value] of Object.entries(groupedArray)) 
   result.push(
     'date': key,
     'transactions': value
   )


console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

【讨论】:

【参考方案3】:

简单

const data = 
  [  id:  1, title: 'Apple Store',             date: '2021-09-10', amount: '$100.00'  
  ,  id: 41, title: 'Zulauf, Walter and Metz', date: '2021-09-10', amount:  '$14.00'  
  ,  id:  9, title: 'Aufderhar PLC',           date: '2021-09-09', amount:  '$78.00'  
  ,  id: 10, title: 'Bayer and Sons',          date: '2021-09-07', amount:  '$67.00'  
  ] 

const res = Object.entries(data.reduce((r,id,title,date,amount)=>
  
  r[date] = r[date] ?? []
  r[date].push(id,title,date,amount)
  return r
  ,)).map(([k,v])=>(date:k,transactions:v))

console.log( res )
.as-console-wrapper  max-height: 100% !important; top: 0 

【讨论】:

【参考方案4】:

使用 lodash,您可以按 date 分组,然后映射到所需的形式:

const input = ["id":1,"title":"Apple Store","date":"2021-09-10","amount":"$100.00","id":41,"title":"Zulauf, Walter and Metz","date":"2021-09-10","amount":"$14.00","id":9,"title":"Aufderhar PLC","date":"2021-09-09","amount":"$78.00","id":10,"title":"Bayer and Sons","date":"2021-09-07","amount":"$67.00"];

const result = _.map(
  _.groupBy(input, 'date'),
  (transactions, date) => ( date, transactions )
)

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

【讨论】:

以上是关于将数据数组转换为 SectionList 组件的分组数据的主要内容,如果未能解决你的问题,请参考以下文章

RN下ScrollView包裹FlatList/SectionList类的组件,在IOS键盘遮挡问题

react native 踩坑之 SectionList state更新 不执行render重新渲染页面

将对象添加到数组并刷新 sectionList

ReactNative进阶(三十七):应用SectionList实现分组列表

React Native SectionList 替换数据键

React-Native SectionList 滚动到Android上的项目