kutyel / linq.ts

🌀LINQ for TypeScript

Home Page:http://kutyel.github.io/linq.ts/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ElementAtOrDefault bugs

chris-findlay opened this issue · comments

ElementAtOrDefault is defined as:

/**
 * Returns the element at a specified index in a sequence or a default value if the index is out of range.
 */
public ElementAtOrDefault(index: number): T {
  return this.ElementAt(index) || undefined
}

However the description doesn't match the implementation (tho the test does), and the implementation is buggy anyway - c.f. FirstOrDefault().

Specifically, indexing off the end (or start, which is not checked for by the way - another bug) should return undefined, rather than throwing, to match the description and .Net behaviour.

Also, if I have a list of numbers that happen to be 0, and I ask for an index in range, I get undefined not 0.

Hi @chris-findlay! Thanks for reporting this.

Specifically, indexing off the end (or start, which is not checked for by the way - another bug) should return undefined, rather than throwing, to match the description and .Net behaviour.

This is doable, but as for the second comment:

Also, if I have a list of numbers that happen to be 0, and I ask for an index in range, I get undefined not 0.

This is rather tricky to achieve in JS/TS, since the default value would be different depending on the type, I can't build a function that returns an empty value for each existing type in the language, how does this work in C#? Does it only return 0, '', [], etc. in the case of some basic native types? Or does it return something else?

.Net returns null for reference types, 0 for numbers and false for boolean. It returns a default instance for structs, e.g DateTime => 1/01/0001 12:00:00 AM.

Given it's JS, I reckon that undefined is a suitable default, or perhaps null, but my point was not what to return when we don't have a valid index, but rather that when we have a valid index, but the value at that index is falsy, we don't get the value, we get undefined instead.

// .Net code that doesn't translate at the moment:
new List<int> { 2, 1, 0, -1, -2}.ElementAtOrDefault(2); // .Net => 0; This code => undefined.

Ok then changing the method so that it doesn't throw and adding '', 0, false to the default return would be what you need? 😉

  • Fixing ElementAt to also throw for -1 etc;
  • Fixing ElementAtOrDefault to check for out of bounds (either side) explicitly and return undefined in those cases;
  • Fixing ElementAtOrDefault to check for in bounds (i.e. the else to the above if) and only return the value at that index, with no fallback clause.

Sorry for the delay @chris-findlay, it was pretty straight-forward to fix! 😉