将数据添加到对象内的数组会添加到所有数组

时间:2018-06-01 11:33:13

标签: javascript arrays

我有一组带有来自用户的上传数据的对象。现在我尝试更改此数组,以便获取chart.js上传图的数据集。

理念是把所有的日子(我从来不知道有多少天),当天每小时上传的数量,并将其放入我的图表的对象数组中。一切都运行得很好,除了我没有每天每小时上传一个上传阵列,看起来一直都是相同的。

根据我的示例变量Uploads,我应该得到两个具有不同数据数组的对象,但它们是相同的。

谁能告诉我哪里弄错了?

//my sample Data
let Uploads = [{
  user: 'user1',
  files: [{
    uploadToServerTime: '21:12:2018 09:15:00'
  }]
}, {
  user: 'user2',
  files: [{
    uploadToServerTime: '22:12:2018 10:17:00'
  }]
}, {
  user: 'user3',
  files: [{
    uploadToServerTime: '22:12:2018 09:14:00'
  }]
}]
//the hourlyUpload Array has a length of 24 for each hour of the day
let hourlyUpload = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let dailyUploadtemp = [];
let dailyUpload = [];
let hour;
let day;
let uploadMoment;
for (let x of Uploads) {
  if (x.hasOwnProperty('files')) {
    for (let y of x.files) {
      if (y.hasOwnProperty('uploadToServerTime')) {
        uploadMoment = moment(y.uploadToServerTime, ['DD.MM.YYYY HH:mm:ss']);
        day = uploadMoment.format('DD.MM.YYYY');
        dailyUploadtemp.push({
          label: day,
          data: hourlyUpload
        })
      }
    }
  }
}
dailyUpload = _.uniqBy(dailyUploadtemp, 'label');
//now I have an array of Objects with a set of empty hours for each day an upload has taken place

for (let x of Uploads) {
  if (x.hasOwnProperty('files')) {
    for (let y of x.files) {
      if (y.hasOwnProperty('uploadToServerTime')) {
        uploadMoment = moment(y.uploadToServerTime, ['DD.MM.YYYY HH:mm:ss']);
        hour = uploadMoment.format('H');
        day = uploadMoment.format('DD.MM.YYYY');
        for (let z of dailyUpload) {
          if (z.label === day) {
          //here is something wrong. The Amount is added to every data, not only to z.data
            z.data[hour] = (z.data[hour] + 1);
          }
        }

      }
    }
  }
}

let ctx = document.getElementById("myChart").getContext("2d");
let myChart = new Chart(ctx, { 
        type: 'line',
        data: {
            labels: ['00:00','01:00','02:00','03:00','04:00','05:00','06:00','07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00', '20:00','21:00','22:00','23:00'],
            datasets: dailyUpload
        },
        options: {
            //responsive: false,
            animation: {
                duration: 1000,
                easing: 'easeOutQuad'
            },
            scales: {
                xAxes: [{
                    type: 'time',
                    time: {
                        parser: "HH:mm",
                        unit: 'hour',
                        unitStepSize: 1,
                        displayFormats: {
                            'minute': 'HH:mm',
                            'hour': 'HH:mm',
                            min: '00:00',
                            max: '23:59'
                        }
                    }
                }]
            }
        }
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<p>There should be two different lines, but I only get two lines with the same datapoints</p>
<canvas id="myChart" width="800" height="400"></canvas>

PS:我很清楚这些循环可以更优雅或更快地解决,但它以这种方式工作,如果我一步一步地这样做,我就更容易理解我在做什么。

1 个答案:

答案 0 :(得分:2)

您的问题在这里:

dailyUploadtemp.push({
   label: day,
   data: hourlyUpload
})

dailyUploadtemp是一个对象,其data属性是对hourlyUpload数组的引用。

您的每个对象都有对同一个数组的引用。因此,如果您要更新此阵列,则修改会反映在所有dailyUpload个对象中。

您可以在data对象中创建dailyUploadTemp属性时克隆数组来解决此问题。 一种方法是使用Array.prototype.slice

dailyUploadtemp.push({
    label: day,
    data: hourlyUpload.slice()
})

&#13;
&#13;
//my sample Data
let Uploads = [{
  user: 'user1',
  files: [{
    uploadToServerTime: '21:12:2018 09:15:00'
  }]
}, {
  user: 'user2',
  files: [{
    uploadToServerTime: '22:12:2018 10:17:00'
  }]
}, {
  user: 'user3',
  files: [{
    uploadToServerTime: '22:12:2018 09:14:00'
  }]
}]
//the hourlyUpload Array has a length of 24 for each hour of the day
let hourlyUpload = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let dailyUploadtemp = [];
let dailyUpload = [];
let hour;
let day;
let uploadMoment;
for (let x of Uploads) {
  if (x.hasOwnProperty('files')) {
    for (let y of x.files) {
      if (y.hasOwnProperty('uploadToServerTime')) {
        uploadMoment = moment(y.uploadToServerTime, ['DD.MM.YYYY HH:mm:ss']);
        day = uploadMoment.format('DD.MM.YYYY');
        dailyUploadtemp.push({
          label: day,
          data: hourlyUpload.slice()
        })
      }
    }
  }
}
dailyUpload = _.uniqBy(dailyUploadtemp, 'label');
//now I have an array of Objects with a set of empty hours for each day an upload has taken place

for (let x of Uploads) {
  if (x.hasOwnProperty('files')) {
    for (let y of x.files) {
      if (y.hasOwnProperty('uploadToServerTime')) {
        uploadMoment = moment(y.uploadToServerTime, ['DD.MM.YYYY HH:mm:ss']);
        hour = uploadMoment.format('H');
        day = uploadMoment.format('DD.MM.YYYY');
        for (let z of dailyUpload) {
          if (z.label === day) {
          //here is something wrong. The Amount is added to every data, not only to z.data
            z.data[hour] = (z.data[hour] + 1);
          }
        }

      }
    }
  }
}

let ctx = document.getElementById("myChart").getContext("2d");
let myChart = new Chart(ctx, { 
        type: 'line',
        data: {
            labels: ['00:00','01:00','02:00','03:00','04:00','05:00','06:00','07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00', '20:00','21:00','22:00','23:00'],
            datasets: dailyUpload
        },
        options: {
            //responsive: false,
            animation: {
                duration: 1000,
                easing: 'easeOutQuad'
            },
            scales: {
                xAxes: [{
                    type: 'time',
                    time: {
                        parser: "HH:mm",
                        unit: 'hour',
                        unitStepSize: 1,
                        displayFormats: {
                            'minute': 'HH:mm',
                            'hour': 'HH:mm',
                            min: '00:00',
                            max: '23:59'
                        }
                    }
                }]
            }
        }
    });
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<p>There should be two different lines, but I only get two lines with the same datapoints</p>
<canvas id="myChart" width="800" height="400"></canvas>
&#13;
&#13;
&#13;

相关问题