簡體   English   中英

將數組動態拆分為子數組

[英]Dynamically split an array into subarrays

const giftcards = [
  {
    fromuserid: 1,
    amount: 10,
    date: new Date(),
    touserid: 11,
  },
  {
    fromuserid: 1,
    amount: 20,
    date: new Date(),
    touserid: 11,

  },
  {
    fromuserid: 2,
    amount: 10,
    date: new Date(),
    touserid: 11,
  },
  {
    fromuserid: 2,
    amount: 10,
    date: new Date(),
    touserid: 11,

  },
  {
    fromuserid: 3,
    amount: 10,
    date: new Date(),
    touserid: 11,

  }
]

我實現了這一點,這在 useEffect 鈎子中顯示:

const giftcards = [
  {
    fromuserid: 1,
    amounts: [{
        amount: 10,
        date: new Date(),
        touserid: 11,
      },
      {
        amount: 20,
        date: new Date(),
        touserid: 11,
      }
    ]
  },

  {
    fromuserid: 2,
    amounts: [{
        amount: 10,
        date: new Date(),
        touserid: 11,

      },
      {
        amount: 10,
        date: new Date(),
        touserid: 11,

      }
    ]
  },
  {
    fromuserid: 3,
    amounts: [{
      amount: 10,
      date: new Date(),
      touserid: 11,

    }]
  }
]

給出的解決方案有效,只是我想讓它變得動態。

意思是,在我的應用程序中,我允許用戶安排數組的排序方式。

例如,

const [sort, setSort] = useState('fromuserid')
   const [results, setResults] = useState([])
   <div>
     <select value={sort} onChange={(e)=> setSort(e.target.value)}>
      <option value='fromuserid'>Sort by Buyer</option>
       <option value='touserid'>Sort by Receiver</option>
       <option value='date'>Sort by Date</option>
     </select>
   </div>

然后在:

useEffect(() => {
  allgiftcards.forEach(({
    fromuserid,
    date,
    from,
    giftcardid,
    message,
    template,
    touserid,
    amount,
    paid
  }) => {
    map.has(fromuserid) || map.set(fromuserid, {
      fromuserid,
      cards: []
    })
    map.get(fromuserid).cards.push({
      date,
      from,
      giftcardid,
      message,
      template,
      touserid,
      amount,
      paid
    })
  })
  setResults([...map.values()])
}, [sort])

這就是我所說的動態。 如果用戶選擇了日期,我希望它看起來像:

useEffect(() => {
  allgiftcards.forEach(({
    fromuserid,
    date,
    from,
    giftcardid,
    message,
    template,
    touserid,
    amount,
    paid
  }) => {
    map.has(date) || map.set(date, {
      date,
      cards: []
    })
    map.get(date).cards.push({
      date,
      from,
      giftcardid,
      message,
      template,
      touserid,
      amount,
      paid
    })
  })
  setResults([...map.values()])
}, [sort])

但在我看來,有一堆 if 和 else 語句會是糟糕的編碼,並且會創建很多額外的代碼,所以尋找一個好的和干凈的解決方案

這真的不是 React(或useEffect來自何處)的問題。 這確實是一個通用的 Javascript 問題,它本身很適合用函數式編程來解決,或者至少用函數式編程的一個主要內容: reduce

在這種情況下,您可以提供作為累加器初始值的第二個參數——在本例中,空對象效果很好。 您可以從數據中選擇任何鍵來存儲結果:

// Choose a key that each object in the set has, e.g. 'fromuserid' or 'touserid'
const group_by = 'fromuserid';

let bucketed = giftcards.reduce(function (acc, x) {
    let pivot = x[group_by]
    let current_vals = (acc.hasOwnProperty(pivot) ? acc[pivot] : []);
    current_vals.push(x);
    acc[pivot] = current_vals;
    return acc
}, {});

console.log(bucketed);

如果您真的需要使用您共享的第二個數據結構,您可以將您的 initialValue 和值的確切位置推入累加器,但希望這展示了如何動態選擇如何對數據進行分組的概念。

此代碼筆展示了如何根據特定屬性動態存儲對象數組。 下面是您可以傳遞給reducer 的回調函數示例——包含在示例中

function groupBy(accum, current, groupKey){
  const val = current[groupKey]
  const {[groupKey]:_, ...content} = current
  if (val in accum){
    accum[val].push(content)
  }
  else accum[val] = [content]
  return accum
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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