1

I am trying to find the largest item in an array.

It was simple enough to solve using the straight-forward, simple, clean, elegant, fast method - iterating the array:

private GetMaxValue(data: Array<RealtimeDataPoint>): number {
    if (data.length === 0)
        return 0;

    var maxValue = data[0].Value;

    for (var i: number = 1; i < data.length; i++) {
        if (data[i].Value > maxValue)
            maxValue = data[i].Value;
    }

    return maxValue;
}

But that's not cool

Then, rather than solving the problem using the easy way, i wanted to try to solve it using .reduce:

private GetMaxValue(data: Array<RealtimeDataPoint>): number {
    var pt: RealtimeDataPoint = data.reduce(function (previousValue: RealtimeDataPoint, currentValue: RealtimeDataPoint, currentIndex: number, array: Array<RealtimeDataPoint>): RealtimeDataPoint {
        if (currentValue.Value > previousValue.Value)
            return currentValue;
        else
            return previousValue;
    });

    if (pt != null)
        return pt.Value;
    else
        return 0;
}

And it's great, and it compiles and all. But it crashes at runtime:

Object doesn't support this action

It seems to indicate that something on the var pt: RealtimeDataPoint = data.reduce(...) line doesn't work, since that's the line it stalls on:

enter image description here

And it's not the .reduce member that it doesn't support, because that's there.

So, two questions:

  • what is wrong with my syntax?
  • why didn't TypeScript realize there was something wrong with my syntax?

Bonus Chatter

  • Internet Explorer 11
  • Chrome 32
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219

2 Answers2

2

Solved it.

The error message from Internet Explorer 11 is:

Object doesn't support this action

The error message from Chrome 32 is:

enter image description here

Reduce of empty array with no initial value

With that the fix is simple; borrow something from the elegant solution:

private GetMaxValue(data: Array<RealtimeDataPoint>): number {
    if (data.length === 0)
       return 0;

    var pt: RealtimeDataPoint = data.reduce(function (previousValue: RealtimeDataPoint, currentValue: RealtimeDataPoint, currentIndex: number, array: Array<RealtimeDataPoint>): RealtimeDataPoint {
        if (currentValue.Value > previousValue.Value)
            return currentValue;
        else
            return previousValue;
    });

    if (pt != null)
        return pt.Value;
    else
        return 0;
}

Given the verbosity of the reduce pattern, and the associated performance penalty, i think i'll stick with the elegant solution.

But at least now there's an example of the reduce syntax in TypeScript.

Note: Any code released into public domain. No attribution required.

Community
  • 1
  • 1
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • Downvote because: 1. This is a really, really long post to get to the point that [].reduce(function() { }) is a runtime error, which isn't even a TypeScript-specific thing 2. Why does your reduce function have 2 extra unused parameters? 3. Why does your reduce function have a bunch of extra type annotations, when it's already contextually typed? 4. Original post doesn't tell us what was in 'data' 5. "Chrome 32" is in 'bonus chatter', but the error message it gave you is the answer to the question? – Ryan Cavanaugh Feb 24 '14 at 01:25
  • 1
    @RyanCavanaugh As StackOverflow says, i should show research effort. a) It's a runtime error in code i didn't write (Typescript compiler wrote it, maybe it's a problem in the generated code) b) because the callback function signature should match the required callback signature c) because i tried it with and without typing, and it still failed d) the data in `data` doesn't matter; the first algorithm worked without knowing what `data` is e) order of operations; i updated the question with the browsers i tried. – Ian Boyd Feb 24 '14 at 12:44
  • 1
    @RyanCavanaugh Oh, and more to the point, if we ignore everything you're being grumpy about, i didn't know what the answer was when i posted the question. It's easy to realize the solution once you have the solution. So when i don't have the solution, i don't know if it's related to typescript - or *what* it's related to. Turns out there *are* things that arbitrarily just don't work in TypeScript. [You would think they would work, but they just don't](http://stackoverflow.com/questions/12950681/typescript-for-in-statment). I assumed `reduce` was another one of those edge cases. – Ian Boyd Feb 24 '14 at 12:48
0

I would use something like Math.max(0, ...data.map(({Value})) => Value)).

Tim
  • 1,018
  • 1
  • 8
  • 12