LINQ SingleOrDefault() equivalent

howardlo picture howardlo · Oct 11, 2015 · Viewed 36.3k times · Source

In Typescript, I use this pattern often:

class Vegetable {
    constructor(public id: number, public name: string) {
    }
}

var vegetable_array = new Array<Vegetable>();
vegetable_array.push(new Vegetable(1, "Carrot"));
vegetable_array.push(new Vegetable(2, "Bean"));
vegetable_array.push(new Vegetable(3, "Peas"));

var id = 1;
var collection = vegetable_array.filter( xvegetable => {
    return xvegetable.id == id;
});
var item = collection.length < 1 ? null : collection[0];

console.info( item.name );

I am thinking about creating a JavaScript extension similar to the LINQ SingleOrDefault method where it returns null if it's not in the array:

var item = vegetable.singleOrDefault( xvegetable => {
    return xvegetable.id == id});

My question is whether there is another way to achieve this without creating a custom interface?

Answer

Amir Popovich picture Amir Popovich · Oct 11, 2015

You can always use Array.prototype.filter in this way:

var arr = [1,2,3];
var notFoundItem = arr.filter(id => id === 4)[0]; // will return undefined
var foundItem = arr.filter(id => id === 3)[0]; // will return 3

Edit
My answer applies to FirstOrDefault and not to SingleOrDefault.
SingleOrDefault checks if there is only one match and in my case (and in your code) you return the first match without checking for another match.

BTW,If you wanted to achieve SingleOrDefault then you would need to change this:

var item = collection.length < 1 ? null : collection[0];

into

if(collection.length > 1)
   throw "Not single result....";

return collection.length === 0 ? null : collection[0];