[英]How to group array items properly
我有一個表,我想呈現按數組中 object 的group
屬性分組的標題。 帶有標題的數組如下所示:
const headers = [
{ label: 'Date', group: '' },
{ label: 'Event', group: '' },
{ label: 'Days Out', group: '' },
{ label: 'T', group: 'Sales Velocity' },
{ label: '-1', group: 'Sales Velocity' },
{ label: '-2', group: 'Sales Velocity' },
{ label: '-3', group: 'Sales Velocity' },
{ label: '-4', group: 'Sales Velocity' },
{ label: 'Sold Last 5', group: 'Ticket Sales' },
{ label: 'Total Sold', group: 'Ticket Sales' },
{ label: 'Sellable cap.', group: 'Ticket Sales' },
{ label: '% sold', group: 'Ticket Sales' },
{ label: 'Availab.', group: 'Ticket Sales' },
{ label: 'Total', group: 'Revenue' },
{ label: 'Holds', group: 'Inventory Status' },
{ label: 'Comp', group: 'Inventory Status' },
{ label: 'Open', group: 'Inventory Status' },
{ label: 'Price cat.', group: 'Inventory Status' },
{ label: 'Avg. price', group: 'Stats' },
{ label: 'First time %', group: 'Stats' },
];
表格組件如下所示:
<TableHead>
<TableRow>
{headers.map((header, index) => (
<TableCellASHeader key={index}>
<TableSortLabel
active={header.column === sorting.orderBy}
direction={sorting.orderDirection}
onClick={() => onClickSort(header.column)}
IconComponent={ArrowDropDownIcon}
>
{/* {header.group} */} // here I need to render group but only once per group
{header.label}
</TableSortLabel>
</TableCellASHeader>
))}
</TableRow>
</TableHead>
我想要的是在header.group
上方渲染header.label
但每組只渲染一次,如下圖所示。 任何代碼示例將不勝感激。
首先,我會將標頭組合到基於組的 object 中。
const groupedHeaders = headers.reduce((acc, curr) => {
let {group, label} = curr;
if (!group) group = 'empty';
if (!acc[group]) {
acc[group] = [label]
} else {
acc[group] = [...acc[group], label]
}
return acc;
}, {});
在將它們組合起來之后, groupedHeaders
看起來像這樣 -
{
empty: [ 'Date', 'Event', 'Days Out' ],
'Sales Velocity': [ 'T', '-1', '-2', '-3', '-4' ],
'Ticket Sales': [
'Sold Last 5',
'Total Sold',
'Sellable cap.',
'% sold',
'Availab.'
],
Revenue: [ 'Total' ],
'Inventory Status': [ 'Holds', 'Comp', 'Open', 'Price cat.' ],
Stats: [ 'Avg. price', 'First time %' ]
}
在 React 部分渲染將使用Object.entries()
來遍歷 object 並相應地顯示。
Object.entries(groupedHeaders).map(([group, labels]) => {
<TableRow>
<HeaderGroup> // you will need to add css with flex/grid
{group === 'empty' ? <EmptyHeader /> : <GroupHeader />}
<SubHeaderGroup> // css required for grouping
{labels.map((header, index) => (
<TableCellASHeader key={index}>
<TableSortLabel
active={header.column === sorting.orderBy}
....
</TableCellASHeader>
))}
</SubHeaderGroup>
</YourHeaderGroup>
</TableRow>
});
查看此代碼沙盒鏈接以獲取完整版本的代碼。
您可以使用new Set()並在其中存儲組名稱,並在每次 map function 運行時檢查。 我在 javascript 中完成了此操作,它將打印組名 1 次和 label 多次。,檢查此
const headers = [
{ label: 'Date', group: '' },
{ label: 'Event', group: '' },
{ label: 'Days Out', group: '' },
{ label: 'T', group: 'Sales Velocity' },
{ label: '-1', group: 'Sales Velocity' },
{ label: '-2', group: 'Sales Velocity' },
{ label: '-3', group: 'Sales Velocity' },
{ label: '-4', group: 'Sales Velocity' },
{ label: 'Sold Last 5', group: 'Ticket Sales' },
{ label: 'Total Sold', group: 'Ticket Sales' },
{ label: 'Sellable cap.', group: 'Ticket Sales' },
{ label: '% sold', group: 'Ticket Sales' },
{ label: 'Availab.', group: 'Ticket Sales' },
{ label: 'Total', group: 'Revenue' },
{ label: 'Holds', group: 'Inventory Status' },
{ label: 'Comp', group: 'Inventory Status' },
{ label: 'Open', group: 'Inventory Status' },
{ label: 'Price cat.', group: 'Inventory Status' },
{ label: 'Avg. price', group: 'Stats' },
{ label: 'First time %', group: 'Stats' },
];
let groups = new Set();
headers.map((header) => {
if(!groups.has(header.group)){
groups.add(header.group);
console.log(header.group);
}
console.log(header.label);
})
Output
Date
Event
Days Out
Sales Velocity
T
-1
-2
-3
-4
Ticket Sales
Sold Last 5
Total Sold
Sellable cap.
% sold
Availab.
Revenue
Total
Inventory Status
Holds
Comp
Open
Price cat.
Stats
Avg. price
First time %
您也可以使用 lodash/uniqBy 來實現這一點。 如果您正在開發企業級應用程序並使用 React/Angular,那么值得考慮。 您可以在一行中達到所需的結果,如下所示 -
import uniqBy from ‘lodash/uniqBy’;
const modifiedArray = uniqBy(headers,’group’);
此外,始終建議您事先檢查您的數據是否未定義。 所以,最好的方法如下 -
import get from ‘lodash/get’;
const modifiedArray = uniqBy((get(headers, ‘response.data’, [])),’group’);
考慮到 headers 數組是 api 的一部分,路徑是 response.data.headers。
請注意:您需要在項目中安裝 lodash 作為您的開發依賴項。 uniqBy 方法將只顯示唯一值而沒有任何重復。
例如,此代碼帶有filter
和map
並可選擇將 arrays 放入 object
const headers = [{ label: 'Date', group: '' }, { label: 'Event', group: '' }, { label: 'Days Out', group: '' }, { label: 'T', group: 'Sales Velocity' }, { label: '-1', group: 'Sales Velocity' }, { label: '-2', group: 'Sales Velocity' }, { label: '-3', group: 'Sales Velocity' }, { label: '-4', group: 'Sales Velocity' }, { label: 'Sold Last 5', group: 'Ticket Sales' }, { label: 'Total Sold', group: 'Ticket Sales' }, { label: 'Sellable cap.', group: 'Ticket Sales' }, { label: '% sold', group: 'Ticket Sales' }, { label: 'Availab.', group: 'Ticket Sales' }, { label: 'Total', group: 'Revenue' }, { label: 'Holds', group: 'Inventory Status' }, { label: 'Comp', group: 'Inventory Status' }, { label: 'Open', group: 'Inventory Status' }, { label: 'Price cat.', group: 'Inventory Status' }, { label: 'Avg. price', group: 'Stats' }, { label: 'First time %', group: 'Stats' }, ]; const empty = headers.filter(el => el.group === '').map(el => el.label) console.log('empty', empty) const sales = headers.filter(el => el.group === 'Sales Velocity').map(el => el.label) console.log('sales', sales) const ticket = headers.filter(el => el.group === 'Ticket Sales').map(el => el.label) console.log('ticket', ticket) const revenue = headers.filter(el => el.group === 'Revenue').map(el => el.label) console.log('revenue', revenue) const inventory = headers.filter(el => el.group === 'Inventory Status').map(el => el.label) console.log('inventory', inventory) const stats = headers.filter(el => el.group === 'Stats').map(el => el.label) console.log('stats', stats) const obj = {} obj.empty = empty obj.sales = sales obj.ticket = ticket obj.revenue = revenue obj.inventory = inventory obj.stats = stats console.log('obj', obj)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.