【问题标题】:Convert a multi-dimensional array of objects to single-dimensional array of objects Javascript将对象的多维数组转换为对象的单维数组Javascript
【发布时间】:2016-01-13 13:55:05
【问题描述】:

我有一个对 Angular 的 ng-repeat 造成严重破坏的多维对象数组,因此我想将其转换为一维数组。我尝试使用forEach,但没有成功。当我在运行函数后尝试使用console.log(newData) 时,它返回一个空数组。是我做得太简单了,还是我犯了一个愚蠢的错误?

//Sample data (allData):

var allData = [{
  "period": 4,
  "uploadDate": "2015-11-19T21:00:00.000Z",
  "section": [{
    "transferCode": 8675309,
    "details": [{
      "voucherNumber": [34, 22],
      "vendor": "jimmy",
      "description": "blah      ",
      "amount": "t        45,555.00"
    }]
  }]
}, {
  "period": 4,
  "uploadDate": "2015-11-19T21:00:00.000Z",
  "section": [{
    "transferCode": 45576543,
    "details": [{
      "voucherNumber": [22, 33],
      "vendor": "Jonson",
      "description": "trap music      ",
      "amount": "t        12,345.00"
    }]
  }]
}]

//code to push to new array:

var newData = [];

function newArray() {
  allData.forEach(function(top) {
    top.section.forEach(function(mid) {
      mid.details.forEach(function(low) {
        newData.push({
          vendor: low.vendor,
          voucherNumber: low.voucherNumber,
          description: low.description,
          amount: low.amount,
          transferCode: mid.transferCode,
          uploadDate: top.uploadDate,
          period: top.period
        })
      })
    })
  })
  return newData;
}
newArray();
document.body.textContent = JSON.stringify(newData);

【问题讨论】:

  • 到底是什么问题?出了什么问题?
  • 公平的问题!让我编辑问题以包含它。谢谢你的收获!
  • @JoshuaSwiss 实际上效果很好。
  • 是的,它确实在这里,只是不在我的代码中!我会玩弄它的。谢谢你至少确认我没有疯。
  • 我建议的一件事是newData 应该被声明(或至少重新初始化)inside 函数。实际上,如果您调用该函数两次,它会将所有内容添加到现有数组的末尾。

标签: javascript arrays foreach


【解决方案1】:

这可能会帮助您避免过于直白...请注意,容器数组被跳过(例如“部分”和“详细信息”)

// Helper functions
function isArray(obj) {return Array.isArray ? Array.isArray(obj) : Object.prototype.toString.call(obj) === '[object Array]';}
function isNumber(val) { return Object.prototype.toString.call(val) === '[object Number]' && isFinite(val);}


// Flatten object
function flatten(arg, out) {
    out = out || {};
    for (var prop in arg) {
        var val = arg[prop];

        if (isArray(val)) {
            for (var i = 0; i < val.length; i++) {

                // introspect if the array is just an array of numbers
                var valin = val[i];
                if (isArray(val) && isNumber(valin)) {

                    // just set to the number array and move along.
                    out[prop] = val;
                    break;
                } else {
                    flatten(valin, out);
                }
            }

        // continue looking deeper
        } else if (typeof val == "object") {
            flatten(val, out); 

        // get the value
        } else {
            out[prop] = val; 
        }
    }
    return out;
}


// Put each flattened object into a new data array
var data = [];
for (var i = 0; i < allData.length; i++) {
    data.push(flatten(allData[i]));
}

console.log(JSON.stringify(data));

【讨论】:

    【解决方案2】:

    我不确定您提出的解决方案是否是您想要的,所以这里解释一下您的数据以及如何构建冗余数据集。

    这是我更改代码的部分:

    "details": [{
        "voucherNumber": [34, 22, 23],
        "vendor": ["jimmy", "sam", "jones"],
        "description": ["blah", "blach", "bluch"],
        "amount": [45555, 232, 345346]
    }]
    

    details 中的每个属性都包含一个长度相同的数组(希望如此)。我假设每个索引都属于一起,例如34, jimmy, blah, 45555

    它的代码部分查找details 中的键,然后查找每个属性数组的长度。然后它遍历长度和键并分配键/值对。收集一个索引的所有值后,将对象推送到结果数组。

    var allData = [{ "period": 4, "uploadDate": "2015-11-19T21:00:00.000Z", "section": [{ "transferCode": 8675309, "details": [{ "voucherNumber": [34, 22, 23], "vendor": ["jimmy", "sam", "jones"], "description": ["blah", "blach", "bluch"], "amount": [45555, 232, 345346] }] }] }, { "period": 4, "uploadDate": "2015-11-19T21:00:00.000Z", "section": [{ "transferCode": 45576543, "details": [{ "voucherNumber": [22, 33], "vendor": ["Jonson", "ronson"], "description": ["trap music", "jesus"], "amount": [12345, 23234] }] }] }];
    
    function newArray(data) {
        var newData = [];
        data.forEach(function (top) {
            top.section.forEach(function (mid) {
                mid.details.forEach(function (low) {
                    var keys = Object.keys(low),
                        length = keys.reduce(function (r, a) { return Math.max(r, low[a].length); }, 0),
                        obj, i = 0;
                    while (i < length) {
                        obj = {
                            uploadDate: top.uploadDate,
                            period: top.period
                        };
                        keys.forEach(function (k) {
                            obj[k] = low[k][i];
                        });
                        newData.push(obj);
                        i++;
                    }
                });
            });
        });
        return newData;
    }
    
    document.write('<pre>' + JSON.stringify(newArray(allData), 0, 4) + '</pre>');

    【讨论】:

      【解决方案3】:

      好的,通过一些有用的建议让它工作并朝着不同的方向发展:

      var allData = [{
        "period": 4,
        "uploadDate": "2015-11-19T21:00:00.000Z",
        "section": [{
          "transferCode": 8675309,
          "details": [{
            "voucherNumber": [34, 22, 23],
            "vendor": ["jimmy", "sam", "jones"],
            "description": ["blah", "blach", "bluch"],
            "amount": [45555, 232, 345346]
          }]
        }]
      },
      {
        "period": 4,
        "uploadDate": "2015-11-19T21:00:00.000Z",
        "section": [{
          "transferCode": 45576543,
          "details": [{
            "voucherNumber": [22, 33],
            "vendor": ["Jonson", "ronson"],
            "description": ["trap music", "jesus"],
            "amount": [12345, 23234]
          }]
        }]
      }];
      
      var newData = [];
      
      function newArray() {
        allData.forEach(function(top) {
          top.section.forEach(function(mid) {
            mid.details.forEach(function(low) {
              low.vendor.forEach(function(vend){
                  low.voucherNumber.forEach(function(vouch) {
                      low.description.forEach(function(desc) {
                          low.amount.forEach(function(amt) {
                              newData.push({
                                  vendor: vend.vendor,
                                  voucherNumber: vouch.voucherNumber,
                                  description: desc.description,
                                  amount: amt.amount,
                                  transferCode: mid.transferCode,
                                  uploadDate: top.uploadDate,
                                  period: top.period
                              });
                          });
                      });
                  });
              });
            });
          });
        });
        return newData;
      }
      newArray();
      document.body.textContent = JSON.stringify(newData);
      // var test = JSON.stringify(newData);
      // console.log(test);
      

      【讨论】:

        猜你喜欢
        • 2017-09-27
        • 2019-06-15
        • 2021-12-28
        • 2016-11-28
        • 2012-11-14
        • 2017-12-12
        • 2013-06-23
        • 2017-05-05
        相关资源
        最近更新 更多