[英]Using Lodash to transform data into object properties instead of a collection by specifying properties value
[英]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()
來提取更新的對象。
_.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>
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>
_.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.