用两个对象替换数组中的对象

时间:2018-04-23 14:14:52

标签: arrays object d3.js replace

我有一个包含结束和开始日期的对象数组。但是,日期之间的时间可能跨越午夜。如果他们这样做,我希望用两个对象替换对象,第一个具有上一个开始日期,结束日期为午夜。第二天的开始时间是第二天00:00,也是之前的结束日期。

因此,例如,如果数组包含诸如此类的对象,

{
  "start": "2016-11-04 22:00",
  "end": "2016-11-05 03:00"
}

我想用两个对象替换该对象,

{
  "start": "2016-11-04 22:00",
  "end": "2016-11-04 24:00"
},
{
  "start": "2016-11-05 00:00",
  "end": "2016-11-05 03:00"
}

以下是我使用data.push()的尝试。显然,这不是这样做的方法:

d3.json("data.json", function(data) {
  var parseTime = d3.timeParse("%Y-%m-%d %H:%M");
  data.forEach(function(d) {
    d.commence = parseTime(d.start);
    d.conclude = parseTime(d.end);
    if (d.commence.getDay() != d.conclude.getDay()) {
      midnight = d.commence.getFullYear() + "-" + d.commence.getMonth() + "-" + d.commence.getDay() + " 24:00";
      morning = d.conclude.getFullYear() + "-" + d.conclude.getMonth() + "-" + d.conclude.getDay() + " 00:00";
      data.push({
        "start": d.start,
        "end": midnight
      }, {
        "start": morning,
        "end": d.end
      })
    }
  });
...

那么当我迭代对象数组时,如何添加或删除对象?

数据就像这样开始,

[
  {
    "start": "2016-11-01 12:00",
    "end": "2016-11-01 22:00"
  },
  {
    "start": "2016-11-02 02:00",
    "end": "2016-11-02 18:00"
  },
  {
    "start": "2016-11-03 09:00",
    "end": "2016-11-03 12:00"
  },
  {
    "start": "2016-11-04 22:00",
    "end": "2016-11-05 03:00"
  },
  {
    "start": "2016-11-06 12:00",
    "end": "2016-11-06 23:00"
  }
]

在控制台中我可以看到它最终看起来像这样,

[
  {
    "start": "2016-11-01 12:00",
    "end": "2016-11-01 22:00",
    "commence": "2016-11-01T12:00:00.000Z",
    "conclude": "2016-11-01T22:00:00.000Z"
  },
  {
    "start": "2016-11-02 02:00",
    "end": "2016-11-02 18:00",
    "commence": "2016-11-02T02:00:00.000Z",
    "conclude": "2016-11-02T18:00:00.000Z"
  },
  {
    "start": "2016-11-03 09:00",
    "end": "2016-11-03 12:00",
    "commence": "2016-11-03T09:00:00.000Z",
    "conclude": "2016-11-03T12:00:00.000Z"
  },
  {
    "start": "2016-11-04 22:00",
    "end": "2016-11-05 03:00",
    "commence": "2016-11-04T22:00:00.000Z",
    "conclude": "2016-11-05T03:00:00.000Z"
  },
  {
    "start": "2016-11-06 12:00",
    "end": "2016-11-06 23:00",
    "commence": "2016-11-06T12:00:00.000Z",
    "conclude": "2016-11-06T23:00:00.000Z"
  },
  {
    "start": "2016-11-04 22:00",
    "end": "2016-10-5 24:00"
  },
  {
    "start": "2016-10-6 00:00",
    "end": "2016-11-05 03:00"
  }
]

完整代码位于github,演示正在gh-pages上运行。

非常感谢任何建议,

由于

1 个答案:

答案 0 :(得分:1)

这是使用flatMap概念(函数式编程)的解决方案:

Array.prototype.flatMap = function(lambda) { 
  return Array.prototype.concat.apply([], this.map(lambda)); 
};

d3.json("data.json", function(data) {

  var parseTime = d3.timeParse("%Y-%m-%d %H:%M");
  var formatEndOfDay = d3.timeFormat("%Y-%m-%d 24:00");
  var formatStartOfDay = d3.timeFormat("%Y-%m-%d %H:%M");

  var result = data.flatMap( d => {
    var start = parseTime(d.start);
    var end = parseTime(d.end);
    if (start.getDay() == end.getDay())
      return [d];
    else {
      var firstPart = { "start": d.start, "end": formatEndOfDay(start) }
      var secondPart = { "start": formatStartOfDay(end.setHours(0)), "end": d.end }
      return [firstPart, secondPart];
    }
  });

  console.log(result);
});

Array.prototype.flatMap = function(lambda) { 
  return Array.prototype.concat.apply([], this.map(lambda)); 
};

var data = [
  {
    "start": "2016-11-01 12:00",
    "end": "2016-11-01 22:00"
  },
  {
    "start": "2016-11-02 02:00",
    "end": "2016-11-02 18:00"
  },
  {
    "start": "2016-11-03 09:00",
    "end": "2016-11-03 12:00"
  },
  {
    "start": "2016-11-04 22:00",
    "end": "2016-11-05 03:00"
  },
  {
    "start": "2016-11-06 12:00",
    "end": "2016-11-06 23:00"
  }
];

var parseTime = d3.timeParse("%Y-%m-%d %H:%M");
var formatEndOfDay = d3.timeFormat("%Y-%m-%d 24:00");
var formatStartOfDay = d3.timeFormat("%Y-%m-%d %H:%M");

var result = data.flatMap( d => {
  var start = parseTime(d.start);
  var end = parseTime(d.end);
  if (start.getDay() == end.getDay())
    return [d];
  else {
    var firstPart = { "start": d.start, "end": formatEndOfDay(start) }
    var secondPart = { "start": formatStartOfDay(end.setHours(0)), "end": d.end }
    return [firstPart, secondPart];
  }
});

console.log(result);
<script src="https://d3js.org/d3.v4.min.js"></script>

提醒一下,这是flatMap的一个例子:列表的每个元素都被转换为多个元素;然后将这些子列表展平以生成列表:

Array.prototype.flatMap = function(lambda) { 
  return Array.prototype.concat.apply([], this.map(lambda)); 
};

console.log([1, 2, 3, 4].flatMap(d => d % 2 == 0 ? [d, d] : [d]))

在我们的例子中,它转换为遍历每个开始/结束元素,如果一个元素在同一天有它的开始和结束,那么我们将它转​​换为1个元素的列表(本身);如果一个元素没有在同一天开始和结束,那么我们将它转​​换为2个元素的列表(第一天/结束日)。

由于javascript没有flatMap的内置实现,我们可以这样创建一个:

Array.prototype.flatMap = function(lambda) { 
  return Array.prototype.concat.apply([], this.map(lambda)); 
};