【问题标题】:Convert an array of objects into a nested object in JavaScript在 JavaScript 中将对象数组转换为嵌套对象
【发布时间】:2018-01-24 10:56:30
【问题描述】:

我有一个 JavaScript 对象数组,如下所示:

var start = [{
  name: 'example name',
  nextItem: {}
},
{
  name: 'example name 2',
  nextItem: {}
},
{
  name: 'example name 3',
  nextItem: {}
}];

我想将此数组转换为单个嵌套对象,其中第一个数组项的内部 nextItem 对象包含下一个数组项的整个对象。例如:

var output = {
  name: 'example name',
  nextItem: {
    name: 'example name 2',
    nextItem: {
      name: 'example name 3',
      nextItem: {}
    }
  }
}

有什么想法吗?

【问题讨论】:

  • 您是否已经尝试过某些东西,但您是否卡在某个地方?
  • 我投票决定将此问题作为题外话结束,因为该问题显示了输入和预期的输出格式,但没有显示任何努力的迹象。这是一项要求,而不是问题陈述。
  • @Rajesh - 这个问题完全有效。如果您询问它有什么问题,您只需要显示尝试的代码。这既是一个特定的编程问题,也是一个软件开发所特有的实用的、可回答的问题。看这里...stackoverflow.com/help/on-topic
  • @Rejesh 如果 SO 如此严格,80% 的问题将被关闭。我们应该像我在第一条评论中所做的那样推动 OP,但关闭,因为这家伙不知道从哪里开始有点极端
  • @Rajesh - 请阅读我给你的链接。它解释了为什么这个问题是完全有效的。

标签: javascript arrays object javascript-objects


【解决方案1】:

您可以在数组上使用 reduce 来添加对象:

function appendRec(obj, newObj) {
    if (obj || obj.nextItem === {}) obj.nextItem = newObj
    else appendRec(obj.nextItem, newObj)
    return obj
}

var output = start.reduce((acc, obj) => {
    return appendRec(acc, obj)
}, { nextItem: { } }).nextItem;

【讨论】:

  • 这将产生一个带有单个 nextItem 的对象,它是列表中的最后一个。
  • 正确,请选择 Yosvel Quinteros 的答案。
  • 我更喜欢我的,是最优雅的 IMO :D
【解决方案2】:

试试这个:

var start = [{
  name: 'example name',
  nextItem: {}
},
{
  name: 'example name 2',
  nextItem: {}
},
{
  name: 'example name 3',
  nextItem: {}
}];

function concat(start) {
    var output = start[0];
    temp = output;
    for(i = 1;i < start.length;i ++) {
        temp.nextItem = start[i];
        temp = temp.nextItem;
    }
    return output;
}

console.log(concat(start));

【讨论】:

    【解决方案3】:

    可以用递归函数来完成:

    function nestItems(items) {
      var currentItem = items[0];
      if (!currentItem) return {};
    
      return {
         name: currentItem.name,
         nextItem: nestItems(items.slice(1))
      };
    }
    
    
    nestItems(start);
    

    【讨论】:

    • 我们真的应该回答这种没有任何努力迹象的问题吗?
    【解决方案4】:

    可能有一种更优雅的方式来做这件事,但这会奏效。 (诀窍是从底部开始,然后逐步向上)。

    var start = [{
      name: 'example name',
      nextItem: {}
    },
    {
      name: 'example name 2',
      nextItem: {}
    },
    {
      name: 'example name 3',
      nextItem: {}
    }];
    
    var output = {};
    
    for (var i = start.length; i > 0; i--) {
      output = { name: start[i - 1].name, nextItem: output };
    }
    
    console.log(output);

    【讨论】:

    • 我们真的应该回答这种没有任何努力迹象的问题吗?
    • @Rajesh - 这个问题完全有效。
    【解决方案5】:

    您可以使用Array.prototype.reduceRight()

    代码:

    var start = [{name: 'example name',nextItem: {}},{name: 'example name 2',nextItem: {}},{name: 'example name 3',nextItem: {}}],
        output  = start.reduceRight(function (a, c) {
          return {
            name: c.name, 
            nextItem: a
          }; 
        });
    
    console.log(output );

    根据@NinaScholz 的评论更新

    【讨论】:

    • 嗯反向?真的吗?为什么不使用reduceRight
    • 代码对于人类来说是第一位的,所以可读性是第一位的
    • 是的,这不公平,它自己的解决方案还可以,所以赞成
    • 我完全同意代码应该放在人类的首位。我进行了编辑以使其更具可读性和更好的缩进.. 感谢您的 cmets
    【解决方案6】:

    您可以将返回的累加器用作嵌套对象的目标,而无需改变原始数组。

    var start = [{ name: 'example name', nextItem: {} }, { name: 'example name 2', nextItem: {} }, { name: 'example name 3', nextItem: {} }],
        result = {};
    
    start.reduce(function (o, a) {
        o.name = a.name;
        o.nextItem = {};
        return o.nextItem;
    }, result);
    
    console.log(result);
    console.log(start);

    ES6 改变原始数组。

    var start = [{ name: 'example name', nextItem: {} }, { name: 'example name 2', nextItem: {} }, { name: 'example name 3', nextItem: {} }],
        result = {};
    
    start.reduce(function (o, a) {
        Object.assign(o, a);
        return o.nextItem;
    }, result);
    
    console.log(result);
    console.log(start);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-13
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      • 1970-01-01
      • 2022-12-18
      • 2020-07-07
      • 2018-03-10
      相关资源
      最近更新 更多