使用 Lodash 将嵌套的对象数组展开

24

我的对象长这样:

const features = [{
                  'name': 'feature1', 'tags':
                  [{'weight':10, 'tagName': 't1'},{'weight':20, 'tagName': 't2'}, {'weight':30, 'tagName': 't3'}]
                  },
                  {
                  'name': 'feature2', 'tags':
                  [{'weight':40, 'tagName': 't1'}, {'weight':5, 'tagName':'t2'}, {'weight':70, 'tagName':'t3'}]
                  },
                  {
                  'name': 'feature3', 'tags':[
                  {'weight':50, 'tagName': 't1'}, {'weight':2, 'tagName': 't2'}, {'weight':80, 'tagName': 't3'}]
                 }]

我希望我的输出看起来像这样:

const features = [{'name':'feature1', 'weight':10, 'tagName':'t1'}, 
                  {'name':'feature1', 'weight':20, 'tagName':'t2'}, ...
                  {'name':'feature3', 'weight':80, 'tagName':'t3'}]

我尝试过使用mergeflatten,但是它们都没有起作用。

更新1: 我尝试了以下操作:

let feat = features;

results = []

_.each(feat, (item) => { 
                        console.log(item);
                        results.push(_.flatten(_.pick(item.tags, 'weight'))); // pick for certain keys. 
                       }

更新 2 这解决了我的问题

_.each(features, (item) => { 
  _.each(item.tags, (itemTag) => { 
    results.push({'name':item.name, 'weight':itemTag.weight, 'tagName':itemTag.tagName})})})

但我想知道是否有更多的 lodash 方式来做这件事!


可能是Underscore to flatten nested array of parent/child objects的重复问题。这篇文章讨论了Underscore,但对于Lodash也应该适用。 - Heretic Monkey
那对我来说并不太有效:/ - suprita shankar
请编辑您的问题,展示您尝试过什么以及为什么没有成功。 - Heretic Monkey
我也尝试了另一种方法来_.merge item.tags,但由于它具有相同的键,所以它没有起作用。我在这里错过了什么? - suprita shankar
1个回答

43
下面的方法使用 flatMap 来展开通过 map 获取的 tags。最后,使用 扩展运算符 分配来自 tagfeature 名称的值。
const result = _.flatMap(features, ({ name, tags }) =>
  _.map(tags, tag => ({ name, ...tag }))
);

const features = [{
    'name': 'feature1',
    'tags': [{
      'weight': 10,
      'tagName': 't1'
    }, {
      'weight': 20,
      'tagName': 't2'
    }, {
      'weight': 30,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature2',
    'tags': [{
      'weight': 40,
      'tagName': 't1'
    }, {
      'weight': 5,
      'tagName': 't2'
    }, {
      'weight': 70,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature3',
    'tags': [{
      'weight': 50,
      'tagName': 't1'
    }, {
      'weight': 2,
      'tagName': 't2'
    }, {
      'weight': 80,
      'tagName': 't3'
    }]
  }
];

const result = _.flatMap(features, ({ name, tags }) =>
  _.map(tags, tag => ({ name, ...tag }))
);

console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

这是一个使用 Array#reduceArray#map 的纯 JavaScript 解决方案,借助 Array#concat 来展开数组。请保留 HTML 标签。
const result = features.reduce(
  (result, { name, tags }) => result
    .concat(tags.map(tag => ({ name, ...tag }))), 
  []
);

const features = [{
    'name': 'feature1',
    'tags': [{
      'weight': 10,
      'tagName': 't1'
    }, {
      'weight': 20,
      'tagName': 't2'
    }, {
      'weight': 30,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature2',
    'tags': [{
      'weight': 40,
      'tagName': 't1'
    }, {
      'weight': 5,
      'tagName': 't2'
    }, {
      'weight': 70,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature3',
    'tags': [{
      'weight': 50,
      'tagName': 't1'
    }, {
      'weight': 2,
      'tagName': 't2'
    }, {
      'weight': 80,
      'tagName': 't3'
    }]
  }
];

const result = features.reduce(
  (result, { name, tags }) => result
    .concat(tags.map(tag => ({ name, ...tag }))), 
  []
);

console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>


谢谢@ryeballar!这太棒了。 - suprita shankar
如果我们只想检索最高权重的内容怎么办?谢谢。 - cilerler
1
@cilerler请将此作为另一个问题发布。 - ryeballar
3
没关系,我明白了。这句话的意思是“返回一个在item.tags中最大值的对象,该对象包含item.name和item.tags中最大值的所有属性,其中item.weight用于比较”。 - cilerler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接