簡體   English   中英

如何正確分組數組項

[英]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 方法將只顯示唯一值而沒有任何重復。

例如,此代碼帶有filtermap並可選擇將 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM