Javascript 中的数组和对象复制

Array and object copy in Javascript

我有以下数据:

[
    {"date":1900,"data":[
        {"name":"Blackbird","value":0},
        {"name":"Seagull","value":1},
        {"name":"Sparrow","value":0}
    ]},
    {"date":1910,"data":[
        {"name":"Owl","value":1}
    ]},
    {"date":1920,"data":[
        {"name":"Eagle","value":0},
        {"name":"Albatross","value":2}
    ]}
]

我需要从中创建一个增量数组。它应该看起来像这样:

[
    [
        {"name":"Blackbird","value":0,"date":1900},
        {"name":"Seagull","value":1,"date":1900},
        {"name":"Sparrow","value":0,"date":1900}
    ],
    [
        {"name":"Blackbird","value":0,"date":1910},
        {"name":"Seagull","value":1,"date":1910},
        {"name":"Sparrow","value":0,"date":1910},
        {"name":"Owl","value":1,"date":1910}
    ],
    [  
        {"name":"Blackbird","value":0,"date":1920},
        {"name":"Seagull","value":1,"date":1920},
        {"name":"Sparrow","value":0,"date":1920},
        {"name":"Owl","value":1,"date":1920},
        {"name":"Eagle","value":0,"date":1920},
        {"name":"Albatross","value":2,"date":1920}
    ]
]

无论我尝试过什么,我总是以我添加到对象的所有日期都等于最后一个值(此处为 1920 年)结束。我了解这些对象仅通过引用进行复制。我已经尝试使用 array.map()(就像在 中一样,但我的问题表述不正确),但我仍然遇到同样的问题。

编辑 这是我试过的一个代码示例:

        var temp = [];
        var b = data.map(function(c, index, main) {
            var year = c.date;
            temp = [];
            main.slice(0, index + 1).map(function(d){
                var t = d.data.map(function(e){
                    e.date = year;
                    return e;
                });
                temp = temp.concat(t);
            });
            return temp;
        });
        console.log(b);

使用map,遍历内部数组,为每个对象设置date 属性等

var data = [
    {"date":1900,"data":[
        {"name":"Blackbird","value":0},
        {"name":"Seagull","value":1},
        {"name":"Sparrow","value":0}
    ]},
    {"date":1910,"data":[
        {"name":"Owl","value":1}
    ]},
    {"date":1920,"data":[
        {"name":"Eagle","value":0},
        {"name":"Albatross","value":2}
    ]}
]

data = data.map(function(obj, i, arr) {
    var o = [];
    
    arr.slice(0, i).forEach(function(item) {
        item.data.forEach(function(data) {
            o.push(Object.assign({}, data))
        });
    });
    
    return o.concat(obj.data.map(function(item) { item.date = obj.date; return item }));
});

document.body.innerHTML = '<pre>' + JSON.stringify(data, null, 4) + '</pre>';

Object.assign with polyfill

试试这个:

var data = [
    {"date":1900,"data":[
        {"name":"Blackbird","value":0},
        {"name":"Seagull","value":1},
        {"name":"Sparrow","value":0}
    ]},
    {"date":1910,"data":[
        {"name":"Owl","value":1}
    ]},
    {"date":1920,"data":[
        {"name":"Eagle","value":0},
        {"name":"Albatross","value":2}
    ]}
];

var result = data.map(function(item) {
  var replacement = [];
  for (var key in item.data) {
     var subItem = item.data[key];
     subItem.date = item.date;
     replacement.push(subItem); 
  }
  return replacement;
});

document.body.innerHTML = '<pre>' + JSON.stringify(result, null, 3) + '</pre>';

这是一个工作示例:

您需要克隆对象才能 "break" 引用。

var data = [
        {
          "date":1900,
           "data":[
            {"name":"Blackbird","value":0},
            {"name":"Seagull","value":1},
            {"name":"Sparrow","value":0}
          ]
        },
        {
          "date":1910,
          "data":[
            {"name":"Owl","value":1}
          ]
        },
        {
          "date":1920,
          "data":[
            {"name":"Eagle","value":0},
            {"name":"Albatross","value":2}
          ]
        }
    ];

    var incremental = [];
    var dataHistory = null;

    for(i = 0; i < data.length; i++){
      var temp = dataHistory ? dataHistory.slice() : []; //.slice to clone array

      //Replace all values with current date.
      for(var j = 0; j < temp.length; j++){
        temp[j] = JSON.parse(JSON.stringify(temp[j])); //Clone object
        temp[j].date = data[i].date;
      }
      
      //Add current date to object.
      for(var j = 0; j < data[i].data.length; j++){
         var aux = {
           name: data[i].data[j].name,
           value: data[i].data[j].value,
           date: data[i].date
         };
        
         temp.push(aux);
      }
      
      dataHistory = temp;
      incremental.push(temp);
    }

document.body.innerHTML = '<pre>' + JSON.stringify(incremental, null, 4) + '</pre>';

如果您使用的是 jQuery,您可以替换为:

temp[j] = JSON.parse(JSON.stringify(temp[j]));

与:

temp[j] = $.extend({}, temp[j]);