0

I am working with some HRV data that I have stored in Arrays in Nodejs. However, whenever I want to acces a value stored in said array it appears as "undefined". The array that I'd like to read is generated by this code:

let rr_data = [456,782,365,234,783,456,987,456,782,365,234,783,456,987,456,782,365,234,783,456,987]
let t = []
rr_data.reduce((current, next, i) => {
        return t[i] = current + next
    })

When I now console log "t" (console.table(t)) it appears like this: console.table(t)

However, whenever I try acccesing one element by itself for example console.log(t.at(0)) or console.log(t[0]) it shows up as "undefined". Why does that happen and how can I prevent it?

Thank you for your help!

  • 1
    Can you explain what `return t[i] = current + next` is supposed to be doing? – Scott Hunter Jan 05 '22 at 13:49
  • It adds the cell values.. – Tasos Jan 05 '22 at 13:50
  • 4
    Only index 0 doesn’t exist, because you don’t provide [`reduce`](//developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) with an initial value. So the first element (index 0) is taken as the initial value and `reduce` starts at index 1. You could’ve added something like `console.log({ current, next, i });` in the callback to help you understand what’s going on. – Sebastian Simon Jan 05 '22 at 13:51
  • Thank you! I was accesing it over t[t.length] and t[0] and thought the whole array is missing. Really stupid mistake. Thank you for helping me! – Sebastian Salletmayer Jan 05 '22 at 13:55
  • Whenever you ask a question like this, please be sure to **include your desired result** in the question. Because you didn't, you have two answers, one of which gives you `456` for the first element of `t` (just the value of `rr_data[0]` unchanged) and one of which gives you `1238` for the first value (the result of adding `rr_data[0]` and `rr_data[1]`). – T.J. Crowder Jan 05 '22 at 14:00
  • Also: `const t = rr_data.reduce((runningTotals, element) => { runningTotals.push(runningTotals.at(-1) + element); return runningTotals; }, [ 0 ]);`. In order to ignore the `0` at the start, you can either use `const [ _0, ...t ] =` instead of `const t =`, or add a `.shift()` after the `.reduce(`…`)`. – Sebastian Simon Jan 05 '22 at 14:08

3 Answers3

1

When you call reduce without any seed value for the accumulator (that is, no second argument), it starts out by calling your callback with the first two values from the array and the index set to 1. So i in your code, on the first callback, with be 1, not 0, and you'll never assign to t[0], so it will remain undefined. (It would also throw an error if your array had no elements in it at all.) This is one of the many reasons reduce is overcomplicated for most use cases outside functional programming with predefined, reusable reducer functions.

If you just want to fill in t with the result of combining elements n and n+1 from your source array, a simple loop is probably your better bet:

for (let index = 0; index < rr_data.length; index += 2) {
    const next = rr_data[index + 1] ?? 0; // In case that's past the end
    t.push(rr_data[index] + next);
}

Live Example:

let rr_data = [456,782,365,234,783,456/*...*/];
let t = [];
for (let index = 0; index < rr_data.length; index += 2) {
    const next = rr_data[index + 1] ?? 0; // In case that's past the end
    t.push(rr_data[index] + next);
}
console.log(t);
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Reduce is the perfect function for this use-case.. – Tasos Jan 05 '22 at 13:56
  • 1
    @Tasos - I disagree, but you're entitled to your opinion as well. Again, no issue with FP folks using it with predefined, tested, reusable reducers, but outside that specialist use case, I (and [some](https://twitter.com/bterlson/status/1099010861065068544) [others](https://twitter.com/jaffathecake/status/1213077702300852224)) have learned over time it's just an overcomplicated loop that triggers maintenance issues down the line. – T.J. Crowder Jan 05 '22 at 13:58
0

There is nothing wrong here.

In Array.reduce() you can pass an initial value. Your problem is that your initial value is undefined, this is why t[0] is not a number.

If you change your code to this it should work:

let rr_data = [456,782,365,234,783,456,987,456,782,365,234,783,456,987,456,782,365,234,783,456,987]
let t = []
rr_data.reduce((current, next, i) => {
        return t[i] = current + next
    }, 0)
console.log(t)
console.log(t[0])
Tasos
  • 1,880
  • 13
  • 19
0

let arr = [456, 782, 365, 234, 783, 456, 987, 456, 782, 365, 234, 783, 456, 987, 456, 782, 365, 234, 783, 456, 987];
let t = [];
arr.forEach ((item, i) => {
if (i != arr.length-1) {
    t[i] = arr[i+1] + arr[i];
}
});
Pierre Janineh
  • 394
  • 2
  • 13