【问题标题】:Array of array to object - javascript数组到对象的数组 - javascript
【发布时间】:2017-06-28 04:25:00
【问题描述】:

我正在循环将数组数组转换为对象,但最终对象只有对象中的最后一项。我很困惑,因为你不能推入像数组这样的对象,而且循环的数量让我很沮丧。需要帮助

这里是 JSbin:http://jsbin.com/torawovicu/edit?js,console

还有如何让对象与数组的顺序相同?

结果应该是这样的:

var newResult =
    [
        {itemcode: 1, item: 'Pen', 'cashier' : 'Sam'},
         {itemcode: 2, item: 'Eraser', 'cashier' : 'Kim'}
    ]

这是我的代码

var list = [
    [
      ['itemCode', 1],
      ['item', 'Pen'],
      ['cashier', 'Sam']
    ],
    [
      ['itemCode', 2],
      ['item', 'Eraser'],
      ['cashier', 'Kim']
    ]
  ]
  //console.log(people.length);

function result(array) {
  var newObj = {};
  var newArr = [];
  for (var x in array) {
    //console.log(array[x])
    var item = array[x];
    for (var y in item) {
      var itemSingle = item[y]
        //console.log(itemSingle);
      for (i = 0; i < itemSingle.length; i = i + 2) {
        newObj[itemSingle[i]] = itemSingle[i + 1];
      }
    }
  }
  return newObj;
}
console.log(result(list));

【问题讨论】:

  • ES6 特性派上用场:list.map(a =&gt; a.reduce((o, [k, v]) =&gt; (o[k]=v, o), {})) 这使用箭头函数和对参数的解构赋值。

标签: javascript arrays object for-loop


【解决方案1】:

您可以使用Array.prototype.mapArray.prototype.reduce 来获得所需的结果,如下所示:

var list = [
  [
    ['itemCode', 1],
    ['item', 'Pen'],
    ['cashier', 'Sam']
  ],
  [
    ['itemCode', 2],
    ['item', 'Eraser'],
    ['cashier', 'Kim']
  ]
];

function result(arr) {
  return arr.map(function(sub) {
    return sub.reduce(function(acc, e) {
      acc[e[0]] = e[1];
      return acc;
    }, {});
  })
}

console.log(result(list));

注意:您不能依赖对象属性的顺序。

【讨论】:

    【解决方案2】:

    您必须使用一个循环来迭代主数组,然后运行循环来迭代每个数组项(也是一个数组)以构造具有您需要的属性的对象。您可以使用 map 作为主循环来返回新数组,其中包含在每次迭代中构造的项目。要构建这些项目,您可以使用forEach

    var list = [
        [
          ['itemCode', 1],
          ['item', 'Pen'],
          ['cashier', 'Sam']
        ],
        [
          ['itemCode', 2],
          ['item', 'Eraser'],
          ['cashier', 'Kim']
        ]
      ];
    
    
    function result(array) {
       let newArray = array.map(function(nestedArray) {
         let obj = {};
         nestedArray.forEach(function(item) {
           obj[item[0]] = item[1];
         });
         return obj;
         
       });
      return newArray;
    }
    console.log(result(list));

    【讨论】:

    • 不要只发布代码,解释问题所在以及如何修复它。
    【解决方案3】:

    有两个问题。

    首先,您永远不会将对象添加到数组或返回数组,您只是返回对象。

    其次,每次循环都使用相同的对象,只是替换它的属性。每次都需要新建一个对象,然后添加到数组中。

    使用for-in 迭代数组也不是一个好主意,使用数字for 循环(或Array.prototype.forEach() 函数)。见Why is using "for...in" with array iteration a bad idea?

    var list = [
        [
          ['itemCode', 1],
          ['item', 'Pen'],
          ['cashier', 'Sam']
        ],
        [
          ['itemCode', 2],
          ['item', 'Eraser'],
          ['cashier', 'Kim']
        ]
      ]
      //console.log(people.length);
    
    function result(array) {
      var newArr = [];
      for (var x = 0; x < array.length; x++) {
        var newObj = {};
        var item = array[x];
        for (var y = 0; y < item.length; y++) {
          var itemSingle = item[y];
          for (var i = 0; i < itemSingle.length; i+=2) {
            newObj[itemSingle[i]] = itemSingle[i + 1];
          }
        }
        newArr.push(newObj);
      }
      return newArr;
    }
    console.log(result(list));

    【讨论】:

    • 非常感谢先生。从昨晚开始我就一直在努力。我只是想不通。这行得通。
    【解决方案4】:

    你可以用一行来完成:

    const newResult = list.map(a => a.map(([k,v]) => ({[k]: v})));
    

    const show = msg => {console.log(JSON.stringify(msg));};
    const list = [
      [
        ['itemCode', 1],
        ['item', 'Pen'],
        ['cashier', 'Sam']
      ],
      [
        ['itemCode', 2],
        ['item', 'Eraser'],
        ['cashier', 'Kim']
      ]
    ];
    
    const newResult = list.map(a => a.map(([k,v]) => ({[k]: v})));
    show(newResult);

    【讨论】:

      【解决方案5】:

      您的问题可以通过使用 JavaScript 中相对较新的功能来解决:地图对象。

      请注意,如果您有一个长度不确定的数组,其中每个元素本身就是一个长度为两个元素的数组,您可以将外部数组转换为地图对象,而不仅仅是一个普通对象。例如const newMapObj = new Map([['a', 1], ['b', 2]]);。将其输入终端然后检查console.log(newMapObj) 会产生以下结果:Map { 'a' =&gt; 1, 'b' =&gt; 2 }。在您的示例中,您可以对两个 list 元素/存储项中的每一个执行此操作,即您最终会得到一个包含 2 个地图对象的数组。

      此类地图对象具有一些方便的功能,例如gethas。有些人还发现他们令人沮丧,因为例如缺少一些有用的方法,比如数组,比如,嗯,map 方法。 (请注意,数组上的map 方法和map/Map 数据对象类型是两个完全不同的东西。我知道,这很令人困惑。)

      下面的代码 sn-p 创建了一个此类地图对象的数组,每个外部数组元素一个(即每个商店“项目”一个),只需一行:

      const newResult = list.map(a => new Map(a));
      

      不幸的是,至少在这个时间点,Stack Exchange 上的代码 sn-p 工具不允许我们像使用普通对象或数组。作为第二好的替代品,下面的代码 sn-p 记录了使用地图对象的一些结果,只是为了证明地图对象实际上是被创建的。

      当我在 Mac 终端中执行相同操作时(即将list 定义为问题中的嵌套数组,然后如上所述计算newResult),console.log(newResult) 显示以下内容:

      [ Map { 'itemCode' => 1, 'item' => 'Pen', 'cashier' => 'Sam' },
        Map { 'itemCode' => 2, 'item' => 'Eraser', 'cashier' => 'Kim' } ]
      

      换句话说,它是一个地图对象数组,而不是一个对象数组。

      如果您对这个最新的 JavaScript 功能感兴趣,您应该查看the MDN documentation on the Map data object

      您是否真的要使用地图对象或普通对象取决于您的用例。上面链接的 MDN 文档有一小部分可帮助您确定是要使用地图对象还是普通对象。

      const list = [
        [
          ['itemCode', 1],
          ['item', 'Pen'],
          ['cashier', 'Sam']
        ],
        [
          ['itemCode', 2],
          ['item', 'Eraser'],
          ['cashier', 'Kim']
        ]
      ];
      
      const newResult = list.map(a => new Map(a));
      console.log('The name for the 1st item is:', newResult[0].get('item'));
      console.log('The cashier for the 2nd item is:', newResult[1].get('cashier'));

      【讨论】:

        【解决方案6】:

        您必须为此使用二维数组,首先您必须为 comlumn 创建一个,然后为 row 创建一个,例如,我在 comulmn 中显示了我添加了名称,并且在行中我添加了职业,让我们编写代码:-

        data = new Array(5)
        info = [0] = new Array(2)
        name [0][0] = "Tom"
        occu [0][1] = "Worker"
        
        info [1] = new Array(2)
        name  [1][0] = "Beryl"
        occu [1][1] = "engineer"
        
        info [2] = new Array(2)
        name [2][0] = "Ann"
        occu [2][1] = "surgeon"
        
        info [3] = new Array(2)
        occu [3][0] = "Bill"
        name [3][1] = "taxman"
        
        info [4] = new Array(2)
        name [4][0] = "Myrtal"
        occu [4][1] = "bank robber"
        

        【讨论】:

        • 他希望结果是对象数组,而不是二维数组。
        • 这和 JSON 有什么关系,就是用 JSON.stringify() 将数组或对象转换为字符串时得到的结果?
        • 这段代码没有从原始数组中获取数据,它只是对所有内容进行硬编码。这根本没用。
        • 您似乎在使用“JSON”这个词来表示“对象”。不是这个意思。
        • 您在为变量 nameoccu 编制索引,而从未为它们分配数组。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-27
        • 2018-08-09
        • 1970-01-01
        • 1970-01-01
        • 2022-09-26
        • 1970-01-01
        相关资源
        最近更新 更多