1

I have an array of start times and stop times for a stopwatch. I need to turn them into one final array that is the actual amount of time that passed for each entry. I always need the length of the final array to be 4, so if there are fewer than 4 times entries, I need a 0 to be in the final array in that place. The amount of input entries will always be 4 or less.

Example input:

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

Desired output:

[ 1111, 5852, 5087, 1685 ]

However, if there are fewer than 4 entries, I want them to be 0 instead.

Example Input:

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

Desired Output:

[ 1111, 5852, 0, 0 ]

Here is the code I currently have:

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))

Right now, this doesn't do anything to make sure that the array is a length of 4 with the extra 0's added on. I know that one thing I could do is something like this:

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

But I was wondering if there was a better way to accomplish this rather than adding this after the map.

1
  • I believe I mentioned above: "The amount of input entries will always be 4 or less" Commented Aug 7, 2016 at 8:24

5 Answers 5

2

One way of doing this is utilizing Array.prototype.map() as follows;

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);

And on a second thought; i think i would in fact do this job with a for of loop as follow;

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);

Sign up to request clarification or add additional context in comments.

Comments

1

What you have is absolutely fine. But if you want an alternative, instead of your loop you can push the missing entries into the array:

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

or in ES2015+

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

That pushes the missing 0s onto your existing output array.

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));

But frankly, I'd stick with the loop. If this is something that comes up a lot for you, you might have a utility function you use for it.

Comments

1

You can use concat() to append on as many additional zeros as you need:

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

Working example:

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))

If you wanted to abstract out the desired number of entries (e.g. using 6 below), you could store that number in a variable and use that to dynamically build the filler array:

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))

Comments

0

You could build a new array with the wanted length and use a default value for non existent Items.

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));

Comments

0

You can use Array.prototype.reduce() to return array if .length of resulting accumulated array is equal to variable or input parameter Number, else utilize Array.prototype.fill(), spread element to fill remaining indexes up to variable

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))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.