使用默认值将数组映射到新数组?

时间:2016-08-07 08:16:54

标签: javascript arrays default-value

我有一系列的秒表开始时间和停止时间。我需要将它们变成一个最终数组,即每个条目的实际传递时间。我总是需要最终数组的长度为4,所以如果少于4个times条目,我需要0在该位置的最终数组中。输入条目的数量始终为4或更少。

示例输入:

[
  { startTime: 1234, stopTime: 2345 },
  { startTime: 3452, stopTime: 9304 },
  { startTime: 2345, stopTime: 7432 },
  { startTime: 4567, stopTime: 6252 }
]

期望的输出:

[ 1111, 5852, 5087, 1685 ]

但是,如果条目少于4个,我希望它们为0

示例输入:

[
  { startTime: 1234, stopTime: 2345 },
  { startTime: 3452, stopTime: 9304 }
]

期望输出:

[ 1111, 5852, 0, 0 ]

以下是我目前的代码:

var times = [
  { startTime: 1234, stopTime: 2345 },
  { startTime: 3452, stopTime: 9304 }
]

function getTimes (arr) {
  var output = arr.map(function (interval) {
    return interval.stopTime - interval.startTime
  })

  return output
}

console.log(getTimes(times))

现在,这并没有做任何事情来确保数组的长度为4,并且添加了额外的0。我知道我能做的一件事是这样的:

while (output.length < 4) {
  output.push(0)
}

但我想知道是否有更好的方法来实现这一点,而不是在map之后添加它。

5 个答案:

答案 0 :(得分:2)

这样做的一种方法是使用Array.prototype.map(),如下所示;

var durations = [{ startTime: 1234, stopTime: 2345 },
                 { startTime: 3452, stopTime: 9304 },
                 { startTime: 2345, stopTime: 7432 },
                 { startTime: 4567, stopTime: 6252 }
                ],
          res = new Array(4).fill();
res = res.map((e,i) => durations[i] ? durations[i].stopTime - durations[i].startTime : 0);
console.log(res);

还有第二个想法;我想我实际上会做一个循环的工作如下;

var durations = [{ startTime: 1234, stopTime: 2345 },
                 { startTime: 3452, stopTime: 9304 },
                 { startTime: 2345, stopTime: 7432 },
                 { startTime: 4567, stopTime: 6252 }
                ],
          res = new Array(4).fill(0),
            i = 0;
for (var duration of durations) res[i++] = duration.stopTime - duration.startTime;
console.log(res);

答案 1 :(得分:1)

您可以使用concat()根据需要附加多个额外的零:

return output.concat([0,0,0,0].slice(arr.length));

工作示例:

var times = [
  { startTime: 1234, stopTime: 2345 },
  { startTime: 3452, stopTime: 9304 }
]

function getTimes (arr) {
  var output = arr
      .map(function (interval) {
          return interval.stopTime - interval.startTime
      })
      .concat([0,0,0,0].slice(arr.length))

  return output
}

console.log(getTimes(times))

如果您想抽象出所需数量的条目(例如,使用下面的6),您可以将该数字存储在变量中并使用它来动态构建填充数组:

var times = [
  { startTime: 1234, stopTime: 2345 },
  { startTime: 3452, stopTime: 9304 }
]

var numEntries = 6
var fill = new Array(numEntries).fill(0)

function getTimes (arr) {
  var output = arr
      .map(function (interval) {
          return interval.stopTime - interval.startTime
      })
      .concat(fill.slice(arr.length))

  return output
}

console.log(getTimes(times))

答案 2 :(得分:1)

你拥有的绝对没问题。但是如果你想要一个替代方案,而不是你的循环,你可以将缺少的条目推送到数组中:

output.push.apply(output, [0, 0, 0, 0].slice(0, 4 - output.length));

或在ES2015 +

output.push(...[0, 0, 0, 0].slice(0, 4 - output.length));

将丢失的0推送到现有的output数组。

var times = [
  { startTime: 1234, stopTime: 2345 },
  { startTime: 3452, stopTime: 9304 }
];

function getTimes (arr) {
  var output = arr.map(function (interval) {
    return interval.stopTime - interval.startTime
  });
  output.push.apply(output, [0, 0, 0, 0].slice(0, 4 - output.length));

  return output;
}

console.log(getTimes(times));

但坦率地说,我坚持循环。如果这对您来说很重要,那么您可能会使用它来实现它。

答案 3 :(得分:0)

您可以构建一个具有所需长度的新数组,并为不存在的项使用默认值。

var times = [{ startTime: 1234, stopTime: 2345 }, { startTime: 3452, stopTime: 9304 }];

function getTimes (arr, len) {
    return Array.apply(null, { length: len }).map(function (_, i) {
        return arr[i] ? arr[i].stopTime - arr[i].startTime : 0;
    });
}

console.log(getTimes(times, 4));

答案 4 :(得分:0)

如果生成的累积数组的Array.prototype.reduce()等于变量或输入参数.length,则可以使用Number返回数组,否则使用Array.prototype.fill(),spread元素填充剩余数据索引到变量

var checkTimes = (times, len) => {
  var res = times.reduce((arr, obj) => [...arr, obj.stopTime - obj.startTime], []);
  return res.length < len ? [...res, ...Array(len - res.length).fill(0)] : res;
};

var times1 = [
  { startTime: 1234, stopTime: 2345 },
  { startTime: 3452, stopTime: 9304 },
  { startTime: 2345, stopTime: 7432 },
  { startTime: 4567, stopTime: 6252 }
];

var times2 = [
  { startTime: 1234, stopTime: 2345 },
  { startTime: 3452, stopTime: 9304 }
];

var checkTimes = (times, len) => {
  var res = times.reduce((arr, obj) => [...arr, obj.stopTime - obj.startTime]
            , []);
  return res.length < len ? [...res, ...Array(len - res.length).fill(0)] : res;
  };

console.log(checkTimes(times1, 4), checkTimes(times2, 4))