我如何从一个对象中生成两个对象,然后用 lodash 将它们除以对象中的一个值

Posted

技术标签:

【中文标题】我如何从一个对象中生成两个对象,然后用 lodash 将它们除以对象中的一个值【英文标题】:How can i make two objects out of one object, dividing them by a value in the object with lodash 【发布时间】:2018-05-28 08:59:33 【问题描述】:

考虑这个对象,有两个使用 NL 语言和一个使用 EN 语言的通道:

[
    
        "name": "De Redactie",
        "channels": [
            
                "name": "headlines",
                "pubDate": "2017-05-15 09:15:00",
                "language": "nl",
                "items": [

                ]
            ,
            
                "name": "headlines English",
                "pubDate": "2017-05-14 18:05:00",
                "language": "en",
                "items": [

                ]
            ,
            
                "name": "politiek",
                "pubDate": "2017-05-14 20:11:00",
                "language": "nl",
                "items": [

                ]
            
        ]
    
]

我怎样才能把它们分开,这样我才能得到这个结果:

[
    
        "name": "De Redactie",
        "channels": [
            
                "name": "headlines",
                "pubDate": "2017-05-15 09:15:00",
                "language": "nl",
                "items": [

                ]
            ,
            
                "name": "politiek",
                "pubDate": "2017-05-14 20:11:00",
                "language": "nl",
                "items": [

                ]
            
        ]
    
    
        "name": "De Redactie",
        "channels": [
            
                "name": "headlines English",
                "pubDate": "2017-05-14 18:05:00",
                "language": "en",
                "items": [

                ]
            
        ]
    
]

请注意,这是 dummyData。实际数据可以包含 x 量的一种语言和 y 量的第二或第三或第四...

我尝试在 lodash 文档中查找正确的功能组合。还尝试了各种复杂的 forEach 结构,但无法理解它。

最好使用 lodash 或 typescript 的解决方案,因为我正在使用 Angular 4。

【问题讨论】:

数据和结果是一个有对象的数组?如果是这样,请更新问题以包含原始数据结构和最终结果。 这是原始数据的简化版本。它太大了,无法在问题中发布 我知道。我不想要所有数据,只想要结构。您是否有一个包含所有数据的对象,或者这个对象是更大数组的一部分?最终结果是不是一个数组? @Ori Drori。我明白了,我以为我的数据结构正确,但我确实忘记添加数组了。现在它是正确的数据结构,抱歉。 @Robby Cornelissen 我感谢您对否决票的解释。但是“不尝试”有点苛刻,我只是忘了添加父数组,我的错。现已修复。 【参考方案1】:

使用 lodash 的方式:

const res = _.chain(arr)
    .flatMap(item => _.map( // get array of channels with parent name
        item.channels,
        channel => _.assign(, channel,  parentName: item.name )
    ))
    .groupBy('language') // group channels by language
    .values() // get channel arrays for each lang
    .map(langArrs => ( // set finished structure
        name: _.first(langArrs).parentName, // get name for lang channels
        channels: _.omit(langArrs, ['parentName']) // set channels without parent name
    ))
    .value();

【讨论】:

【参考方案2】:

使用Array#map 迭代数组。对于每个对象,使用destructuring 和object rest 提取通道数组。使用Array#reduce 迭代频道并将具有相同语言的频道分组到Map。通过传播Map's values iterator 转换回数组。

通过映射对象并将组分配为对象的channels 属性来创建对象数组。通过扩展到Array#concat 来展平数组:

const data = ["name":"De Redactie","channels":["name":"headlines","pubDate":"2017-05-15 09:15:00","language":"nl","items":[],"name":"headlines English","pubDate":"2017-05-14 18:05:00","language":"en","items":[],"name":"politiek","pubDate":"2017-05-14 20:11:00","language":"nl","items":[]]];

const result = [].concat(...data.map(( channels, ...rest ) => 
  const channelGroups = [...channels.reduce((m, channel) => 
    m.has(channel.language) || m.set(channel.language, []);
    m.get(channel.language).push(channel);
  
    return m;
  , new Map()).values()];
  
  return channelGroups.map((channels) => (
    ...rest,
    channels
  ));
));

console.log(result);

【讨论】:

使用channels.reduce((m, channel) 我得到Type 'IterableIterator<any>' is not an array type 这很奇怪,因为通道绝对是一个数组。 @MartijnvandenBergh - reduce 结果是一个 Map,而不是一个数组。 .values() 产生一个迭代器。

以上是关于我如何从一个对象中生成两个对象,然后用 lodash 将它们除以对象中的一个值的主要内容,如果未能解决你的问题,请参考以下文章

C#如何从Tao库中获取OpenGL中生成的对象的大小

如何在 R 中生成对象的排列或组合?

从 Django 模型中生成 JavaScript 对象

jQuery 在附加到 DOM 之前从元素中生成变量

如何在unity2d中生成对象? [关闭]

AS3 Flash:从 1 个类中生成 2 个相同的对象?