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

brjng4g3  于 2023-10-22  发布在  React
关注(0)|答案(6)|浏览(164)

我坦率地承认,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的输出转换为数组直接删除了键,我得到了分组数据,但没有明确的节头值。
同样,可能有一些非常简单的方法来解决这个问题,数据总是以平面数组的形式出现。我感谢任何人的指导、帮助或例子。

eagi6jfj

eagi6jfj1#

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,在每个元素上循环,看看是否能找到元素,并将当前元素推入列表

0sgqnhkj

0sgqnhkj2#

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>
wrrgggsh

wrrgggsh3#

简单

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 }
5lhxktic

5lhxktic4#

使用lodash,你可以按date分组,然后Map到所需的表单:

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>
xu3bshqb

xu3bshqb5#

你可以用loadash

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

tez616oj6#

下面是我写的一个TypeScript实用函数,它可以做类似的事情:

// from https://stackoverflow.com/a/49752227
type KeyOfType<T, V> = keyof {
  [P in keyof T as T[P] extends V? P: never]: any
};

// data[key] must be string, number, or symbol
export function groupBy<T>(data: T[], key: KeyOfType<T, string | number | symbol>) {
  const collect: {[index: string | number | symbol]: T[]} = {};
  for (let item of data) {
    const key_value = item[key] as string | number | symbol;
    if (key_value in collect) collect[key_value].push(item);
    else collect[key_value] = [item];
  }
  return collect;
};

关于上述数据:

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'},
];
groupBy(data, 'date');
// yields:
{
  '2021-09-07': [{id: 10, title: 'Bayer and Sons', date: '2021-09-07', amount: '$67.00'}],
  '2021-09-09': [{id: 9, title: 'Aufderhar PLC', date: '2021-09-09', amount: '$78.00'}],
  '2021-09-10': [
    {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'},
  ],
};

对于多个密钥:

type Indexable = string | number | symbol;

export function multiGroupBy<T>(data: T[], ...keys: KeyOfType<T, Indexable>[]) {
  const collect_keys: Indexable[][] = [];
  const collect_values: T[][] = [];
  for (let item of data) {
    const key_value: Indexable[] = [];
    for (let key of keys) {
      key_value.push(item[key] as Indexable);
    }
    let key_ix = collect_keys.indexOf(key_value);
    if (key_ix == -1) {
      key_ix = collect_keys.length;
      collect_keys.push(key_value);
      collect_values.push([item]);
    } else collect_values[key_ix].push(item);
  }
  return [collect_keys, collect_values];
}

相关问题