Dans TypeScript, j'utilise souvent ce modèle:
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 );
Je pense à créer une extension JavaScript similaire à la méthode LINQ SingleOrDefault
où elle renvoie null
si elle n'est pas dans le tableau:
var item = vegetable.singleOrDefault( xvegetable => {
return xvegetable.id == id});
Ma question est de savoir s'il existe un autre moyen d'y parvenir sans créer une interface personnalisée?
Vous pouvez toujours utiliser Array.prototype.filter de cette manière:
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
Modifier
Ma réponse s'applique à FirstOrDefault
et non à SingleOrDefault
.SingleOrDefault
vérifie s'il n'y a qu'une seule correspondance et dans mon cas (et dans votre code) vous retournez la première correspondance sans rechercher une autre correspondance.
BTW, si vous vouliez atteindre SingleOrDefault
alors vous auriez besoin de changer ceci:
var item = collection.length < 1 ? null : collection[0];
dans
if(collection.length > 1)
throw "Not single result....";
return collection.length === 0 ? null : collection[0];
Si vous voulez trouver un élément dans le tableau, je vous suggère d'utiliser méthode de recherche ES6 , comme ceci:
const inventory = [
{ name: 'apples', quantity: 2 },
{ name: 'bananas', quantity: 0 },
{ name: 'cherries', quantity: 5 }
];
const result = inventory.find(fruit => fruit.name === 'cherries');
console.log(result) // { name: 'cherries', quantity: 5 }
C'est plus rapide et plus facile à lire, car vous n'avez pas besoin d'écrire collection[0]
.
Soit dit en passant, SingleOrDefault
de C # lève une exception s'il a trouvé plusieurs éléments. Ici, vous essayez de créer une extension FirstOrDefault
.
Si la réutilisation n'est pas nécessaire, vous pouvez implémenter un singleOrDefault
en appliquant une simple fonction réduire :
Dans ce cas, la fonction de réduction n'est calculée que lorsque le tableau n'est pas vide. Il lance lorsque la longueur est supérieure à 1, sinon il renvoie le seul élément. Lorsque le tableau est vide, le paramètre de valeur par défaut de la fonction de réduction est renvoyé: dans ce cas null
.
Par exemple:
[].reduce(function(acc, cur, idx, src) {
if (src.length > 1) {
throw 'More than one found';
}
return src[0];
}, null);
Maintenant, il existe une bibliothèque qui fournit des collections fortement typées et interrogeables en TypeScript.
La bibliothèque s'appelle ts-generic-collections.
Code source sur GitHub:
https://github.com/VeritasSoftware/ts-generic-collections
Avec cette bibliothèque, vous pouvez écrire des requêtes comme indiqué ci-dessous:
let owners = new List<Owner>();
let owner = new Owner();
owner.id = 1;
owner.name = "John Doe";
owners.add(owner);
owner = new Owner();
owner.id = 2;
owner.name = "Jane Doe";
owners.add(owner);
let pets = new List<Pet>();
let pet = new Pet();
pet.ownerId = 2;
pet.name = "Sam";
pet.sex = Sex.M;
pets.add(pet);
pet = new Pet();
pet.ownerId = 1;
pet.name = "Jenny";
pet.sex = Sex.F;
pets.add(pet);
//query to get owners by their pet's gender/sex
let ownersByPetSex = owners.join(pets, owner => owner.id, pet => pet.ownerId, (x, y) => new OwnerPet(x,y))
.groupBy(x => [x.pet.sex])
.select(x => new OwnersByPetSex(x.groups[0], x.list.select(x => x.owner)));
expect(ownersByPetSex.toArray().length === 2).toBeTruthy();
expect(ownersByPetSex.toArray()[0].sex == Sex.F).toBeTruthy();
expect(ownersByPetSex.toArray()[0].owners.length === 1).toBeTruthy();
expect(ownersByPetSex.toArray()[0].owners.toArray()[0].name == "John Doe").toBeTruthy();
expect(ownersByPetSex.toArray()[1].sex == Sex.M).toBeTruthy();
expect(ownersByPetSex.toArray()[1].owners.length == 1).toBeTruthy();
expect(ownersByPetSex.toArray()[1].owners.toArray()[0].name == "Jane Doe").toBeTruthy();