簡體   English   中英

Map 對象數組以及使用 Ramda 的父屬性

[英]Map array of objects together with the parent property using Ramda

我是函數式編程和 ramda 的新手。 我有一個案例,可以很容易地以命令式的方式解決,但我在聲明式的方式上遇到了困難。 我有以下結構,它描述了多個庫存。

inventories = [
  {
    id: 'Berlin',
    products: [{ sku: '123', amount: 99 }],
  },
  {
    id: 'Paris',
    products: [
      { sku: '456', amount: 3 },
      { sku: '789', amount: 777 },
    ],
  },
]

我想要做的是將其轉換為產品的平面列表,其中包含額外的信息,如inventoryIdinventoryIndexproductIndex

products = [
  { inventoryId: 'Berlin', inventoryIndex: 1, sku: '123', amount: 99, productIndex: 1 },
  { inventoryId: 'Paris', inventoryIndex: 2, sku: '456', amount: 3, productIndex: 1 },
  { inventoryId: 'Paris', inventoryIndex: 2, sku: '789', amount: 777, productIndex: 2 },
]

正如我之前所寫,以命令式的方式執行此操作不是問題。

function enrichProductsWithInventoryId(inventories) {
  const products = []
  for (const [inventoryIndex, inventory] of inventories.entries()) {
    for (const [productIndex, product] of inventory.products.entries()) {
      product.inventoryId = inventory.id
      product.inventoryIndex = inventoryIndex + 1
      product.productIndex = productIndex + 1
      products.push(product)
    }
  }

  return products
}

問題是當我嘗試用 ramda 解決這個問題時。 我不知道如何在映射產品時訪問inventoryId 很高興看到一段使用 ramda 編寫的代碼,它與上面的代碼相同。

干杯,托馬斯

您可以使用flatMap輕松完成此操作。

 const inventories = [ { id: "Berlin", products: [{ sku: "123", amount: 99 }] }, { id: "Paris", products: [ { sku: "456", amount: 3 }, { sku: "789", amount: 777 } ] } ]; const products = inventories.flatMap((inventory, inventoryIndex) => inventory.products.map((product, productIndex) => ({ inventoryId: inventory.id, inventoryIndex: inventoryIndex + 1, sku: product.sku, amount: product.amount, productIndex: productIndex + 1 }))); console.log(products);

請注意,在addIndexflatMap被稱為chain ,但您需要將索引添加到它。

 const inventories = [ { id: "Berlin", products: [{ sku: "123", amount: 99 }] }, { id: "Paris", products: [ { sku: "456", amount: 3 }, { sku: "789", amount: 777 } ] } ]; const chainIndexed = R.addIndex(R.chain); const mapIndexed = R.addIndex(R.map); const products = chainIndexed((inventory, inventoryIndex) => mapIndexed((product, productIndex) => ({ inventoryId: inventory.id, inventoryIndex: inventoryIndex + 1, sku: product.sku, amount: product.amount, productIndex: productIndex + 1 }), inventory.products), inventories); console.log(products);
 <script src="https://unpkg.com/ramda@0.27.1/dist/ramda.min.js"></script>

我可能會以與 Aadit 建議的方式類似的方式執行此操作,盡管我的框架會有所不同,並使用參數解構

 const convert = (inventories) => inventories.flatMap (({id: inventoryId, products}, i, _, inventoryIndex = i + 1) => products.map ( ({sku, amount}, i, _, productIndex = i + 1) => ({inventoryId, inventoryIndex, sku, amount, productIndex}) ) ) const inventories = [{id: "Berlin", products: [{sku: "123", amount: 99}]}, {id: "Paris", products: [{sku: "456", amount: 3}, {sku: "789", amount: 777}]}] console.log (convert (inventories));
 .as-console-wrapper {max-height: 100%;important: top: 0}

但是,如果您想將其分解為更小的組件,Ramda 可以幫助您編寫它們並將它們粘合在一起成為一個整體。 如果我們試圖描述我們正在做的事情,我們可能會將其視為四個步驟。 我們將id字段重命名為inventoryId ,我們為我們的庫存添加一個運行索引,並為每組products添加一個單獨的索引,我們通過提升products arrays 與它們的父級合並來非規范化/扁平化我們的嵌套列表。

所有這些都是潛在的可重用轉換。 如果我們願意,我們可以為這些分解出單獨的輔助函數,然后使用 Ramda 將它們組合成一個 function。 它可能看起來像這樣:

 const {pipe, toPairs, map, fromPairs, addIndex, chain, merge, evolve} = R const mapKeys = (cfg) => pipe ( toPairs, map (([k, v]) => [cfg [k] || k, v]), fromPairs ) const addOrdinals = (name) => addIndex (map) ((x, i) => ({... x, [name]: i + 1 })) const promote = (name) => chain (({[name]: children, ...rest}) => map (merge(rest), children)) const transform = pipe ( map (mapKeys ({id: 'inventoryId'})), addOrdinals ('inventoryIndex'), map (evolve ({products: addOrdinals ('productIndex')})), promote ('products') ) const inventories = [{id: "Berlin", products: [{sku: "123", amount: 99}]}, {id: "Paris", products: [{sku: "456", amount: 3}, {sku: "789", amount: 777}]}] console.log (transform (inventories))
 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>

這涉及到更多代碼,但我們所做的是創建了許多有用的小函數,並通過組合對這些小函數的調用來使我們的主 function 更具聲明性。 在你的項目中可能值得做,也可能不值得做,但它當然值得考慮。

暫無
暫無

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

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