【问题标题】:Transform array of data into grouped data for SectionList component将数据数组转换为 SectionList 组件的分组数据
【发布时间】: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 的输出直接转换为数组会丢弃键,我已经得到分组数据,但节标题没有明确的值。

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

【问题讨论】:

标签: javascript arrays react-native lodash


【解决方案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>

      【讨论】:

        猜你喜欢
        • 2018-09-12
        • 1970-01-01
        • 2019-03-08
        • 2018-02-20
        • 2014-07-03
        • 1970-01-01
        • 2012-01-23
        • 2020-12-24
        • 1970-01-01
        相关资源
        最近更新 更多