簡體   English   中英

使用 lodash 將數據轉換為對象屬性而不是集合

[英]Using lodash to transform data into object properties instead of a collection

繼續我之前關於使用 lodash 轉換數據的問題,這次我要求輸出是一個對象屬性而不是一個集合。 我很感激你的幫助,如果有人也能指導我從哪里開始正確地開始,那么我對這些概念有更好的理解

樣本數據

var sample = [{
    "changeType": 1,
    "type": "changeAccount",
    "updated": {
      "id": 71,
      "company": 124201,
      "user": 8622
    }
  },
  {
    "changeType": 2,
    "type": "changeAccount",
    "updated": {
      "id": 70,
      "company": 124201,
      "user": 8622
    }
  },
  {
    "changeType": 1,
    "type": "changeproduct",
    "updated": {
      "id": 15,
      "company": 124201,
      "user": 8622
    }
  }
]

// what I tried
var result = _.mapValues(_.groupBy(sample, "type"), x => x.map(y => _.omit(y, "changeType")));

console.log(result);

預期結果

var output = {
    "ChangeAccount": {

        "changeTypes":
            {
                "add": [{}], //type 1

                "remove": [{}] //type 2


            }
    },

    "ChangeProduct":{

        "changeTypes":
            {
                "add": [{}], //type 1

                "remove": [{}] //type 2  will be empty in this case
            }
    }
}

上一個問題答案

const fn = arr =>
  map(groupBy(arr, 'type'), (group, type) => ({ // group and map to array of objects
    type,
    ...mapValues( // spread after mapping the values to extract updated
      groupBy(group, 'changeType'), // group again by changeType
      items => items.map(item => pick(item, 'updated') // extract the updated from each item
    ))
  }))

**以前的答案輸出**

 [
    {
        [
            {
                "updated": {
                    "id": 71,
                    "company": 124201,
                    "user": 8622
                }
            }
            ],
        [
            {
                "updated": {
                    "id": 70,
                    "company": 124201,
                    "user": 8622
                }
            }
            ],
        "type": "changeAccount"
    },
        {
            [
                {
                    "updated": {
                        "id": 15,
                        "company": 124201,
                        "user": 8622
                    }
                }
                ],
            "type": "changeproduct"
        }

嘗試解決方案,我知道它看起來有點亂。 幾乎沒有什么需要改進的,但你會得到一個想法。

const result = sample.reduce((acc, obj)=> {
  let addOrRemove  = obj.changeType === 1 ? 'add' : 'remove';
  if(acc[obj.type] && acc[obj.type].changeTypes &&  acc[obj.type].changeTypes[addOrRemove]) {    
    acc[obj.type].changeTypes[addOrRemove].push({updated: obj.updated})
  } else  {
    acc[obj.type] = acc[obj.type] ? { ...acc[obj.type]}:{changeTypes: {}};
    acc[obj.type].changeTypes[addOrRemove] = [{updated :obj.updated}];
  }
  return acc;
}, {})

我會說你不會被迫使用 lodash,你可以只用普通的 javascript 來實現。 但是,由於您需要使用 lodash,這里有一個簡單的方法。 您可以根據您的要求的難度來簡化它。

const omitChangeType = ({changeType, ...rest}) => rest // this is just ES6, don't need lodash for this

_.mapValues(
    _.groupBy(sample, "type"), 
    (x) => ({ 
        changeTypes: { 
            add: x.filter(_.matches({ changeType: 1 })).map(omitChangeType), 
            remove: x.filter(_.matches({ changeType: 2 })).map(omitChangeType)
        }})
    )

我喜歡這個解決方案的地方在於,您對最終結構的外觀有所了解。

輸出:

{
  "changeAccount": {
    "changeTypes": {
      "add": [
        {
          "type": "changeAccount",
          "updated": {
            "id": 71,
            "company": 124201,
            "user": 8622
          }
        }
      ],
      "remove": [
        {
          "type": "changeAccount",
          "updated": {
            "id": 70,
            "company": 124201,
            "user": 8622
          }
        }
      ]
    }
  },
  "changeproduct": {
    "changeTypes": {
      "add": [
        {
          "type": "changeproduct",
          "updated": {
            "id": 15,
            "company": 124201,
            "user": 8622
          }
        }
      ],
      "remove": []
    }
  }
}

在我的解決方案中,我使用了一些 ES 解構,如果您要處理這樣的數據修改,這是一個非常方便的功能。 如果您不熟悉它, 請看一看 另外,我不確定您的意圖是只是省略 changeType 還是要提取每個對象的更新部分。 如果您只想選擇每個對象的更新屬性,只需通過以下函數名稱更改每個外觀,並添加此函數聲明:

const pickUpdated = ({updated}) => updated

所以,而不是.map(omitChangeType)你做.map(pickUpdated)

在這種情況下,輸出將如下所示

{
  "changeAccount": {
    "changeTypes": {
      "add": [
        {
          "id": 71,
          "company": 124201,
          "user": 8622
        }
      ],
      "remove": [
        {
          "id": 70,
          "company": 124201,
          "user": 8622
        }
      ]
    }
  },
  "changeproduct": {
    "changeTypes": {
      "add": [
        {
          "id": 15,
          "company": 124201,
          "user": 8622
        }
      ],
      "remove": []
    }
  }
}

如果您有任何疑問,請隨時發表評論

您需要_.groupBy()然后使用_.mapValues()來轉換組(使用generateChangeTypes )。 generateChangeTypes - 在組中使用_.groupBy()並將類型號轉換為添加/刪除(使用changeTypes對象),然后使用_.mapValues()_.map()來提取更新的對象。

版本 1 - 使用_.flow()管道

 const { flow, partialRight: pr, groupBy, mapValues, map, } = _ const changeTypes = { 1: 'add', 2: 'remove' } const generateChangeTypes = flow( pr(groupBy, o => changeTypes[o.changeType]), // group by changeType pr(mapValues, g => map(g, 'updated')) // extract the updated ) const transform = flow( pr(groupBy, 'type'), pr(mapValues, group => ({ changeTypes: { add: [], // default remove: [], // default ...generateChangeTypes(group) } })) ) const sample = [{"changeType":1,"type":"changeAccount","updated":{"id":71,"company":124201,"user":8622}},{"changeType":2,"type":"changeAccount","updated":{"id":70,"company":124201,"user":8622}},{"changeType":1,"type":"changeproduct","updated":{"id":15,"company":124201,"user":8622}}] const result = transform(sample) console.log(result)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

版本 2 - 使用 lodash 鏈接

 const sample = [{"changeType":1,"type":"changeAccount","updated":{"id":71,"company":124201,"user":8622}},{"changeType":2,"type":"changeAccount","updated":{"id":70,"company":124201,"user":8622}},{"changeType":1,"type":"changeproduct","updated":{"id":15,"company":124201,"user":8622}}] const changeTypes = { 1: 'add', 2: 'remove' } const result = _(sample) .groupBy('type') .mapValues(group => ({ changeTypes: { add: [], // default remove: [], // default ..._(group) .groupBy(o => changeTypes[o.changeType]) // group by changeType text .mapValues(g => _.map(g, 'updated')) // extract the updated .value() } })) .value() console.log(result)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

版本 3 - 帶有_.flow() lodash/fp

 const { flow, groupBy, mapValues, map, } = _ const changeTypes = { 1: 'add', 2: 'remove' } const generateChangeTypes = flow( groupBy(o => changeTypes[o.changeType]), // group by changeType mapValues(map('updated')) // extract the updated ) const transform = flow( groupBy('type'), mapValues(group => ({ changeTypes: { add: [], // default remove: [], // default ...generateChangeTypes(group) } })) ) const sample = [{"changeType":1,"type":"changeAccount","updated":{"id":71,"company":124201,"user":8622}},{"changeType":2,"type":"changeAccount","updated":{"id":70,"company":124201,"user":8622}},{"changeType":1,"type":"changeproduct","updated":{"id":15,"company":124201,"user":8622}}] const result = transform(sample) console.log(result)
 <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

暫無
暫無

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

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