简体   繁体   中英

Transform array of data into grouped data for SectionList component

I'll freely admit that Javascript is not my strongest language, and React Native is very new, so, there may be an obviously easy way to do this that I'm not seeing.

I've got an API that presents some transaction data in a simple structure:

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

I want to present this data using a SectionList component, with the transactions in sections by date. My (likely crude) attempt to solve this was going to be to transform this data into the following structure:

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

But I'm honestly lost as to how to transform this data (or if there's a better way to solve this problem). I started by using Lodash's groupBy function, which seemed promising, but it looks like SectionList doesn't want an object, it wants an array.

Transforming the output of groupBy into an array straight off drops the keys and I've got grouped data but no clear value for the section header.

Again, there's probably some deviously simple way to address this, data comes in as a flat array all the time. I appreciate any guidance, assistance, or examples anybody can point me to.

 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)

Given an array, whenever your result is expecting to have same number of elements, use map , but since your result has different number of elements, use reduce as shown above. The idea is by having reduce , loop over each element, see if you can find the element, and push the current element into the list

The lodash groupBy just helps you with group data, you should process grouped data by converting it into your format.

 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>

simply

 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 }

With lodash you can group by the date then map to the required form:

 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>

you could use loadash

var result = _(data)
    .groupBy(item => item.date)
    .map((value, key) => ({date: key, transactions: value}))
    .value();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM