août
2007
<a href= »http://blogs.msdn.com/mitsufu »>Mitsu</a> s’est lancé dans une série de quizz (2 pour l’instant) relatifs à C# 3.0.
J’ai fait un truc assez rigolo hier soir et, du coup, je lance aussi mon Quizz pour comparer avec ma solution.
On a un type anonyme avec trois propriétés : Nom (string), Prenom (string), Ville (string).
On a une requête LINQ (To XML dans mon cas mais on s’en fout) qui doit retourner un IEnumerable de notre type avec un Distinct sur le Nom et le Prenom et sur la ville quand elle n’est pas nulle.
Par exemple, sur le xml suivant,
<Persons>
<Person>
<Person>
<Nom> »Durand »</Nom>
<Prenom> »Pierre »</Prenom>
</Person>
<Nom> »Durand »</Nom>
<Prenom> »Pierre »</Prenom>
<Ville> »Paris »</Ville>
</Person>
<Person>
<Nom> »Durand »</Nom>
<Prenom> »Pierre »</Prenom>
</Person>
<Person>
<Nom> »Durand »</Nom>
<Prenom> »Pierre »</Prenom>
<Ville> »Toulouse »</Ville>
</Person>
<Person>
<Nom> »Durand »</Nom>
<Prenom> »Luc »</Prenom>
<Ville> »Paris »</Ville>
</Person>
<Person>
<Nom> »Dupont »</Nom>
<Prenom> »Pierre »</Prenom>
</Person>
</Persons>
on doit récupérer :
Durand Pierre Paris
Durand Pierre Toulouse
Durand Luc Paris
Dupont Pierre null
Comment faire ceci ?
Vu que je viens de déménager et que je n’ai pas encore récupérer Internet chez moi (trop dur :() et que je suis en vacances une partie de la semaine prochaine ne comptez pas avoir la réponse tout de suite. Ca vous donnera le temps de réfléchir :p
Je n’avais jamais utilisé le mot clé let.
Merci beaucoup Simon pour avoir comblé une de mes lacunes
XDocument doc = XDocument.Load(« ..\..\XMLFile1.xml »);
var allPersons = (from elem in doc.Element(« Persons »).Elements(« Person »)
select new
{
Nom = elem.Element(« Nom »).Value,
Prenom = elem.Element(« Prenom »).Value,
Ville = elem.Element(« Ville ») != null ? elem.Element(« Ville »).Value : null
}).Distinct();
var filteredPersons = from person in allPersons
let nonNullCount = (from p in allPersons
where p.Nom == person.Nom
&& p.Prenom == person.Prenom
&& p.Ville != null
select p).Count()
where person.Ville != null || nonNullCount == 0
select person;
Perso, j’avais pensé à ceci :
{ <br />
public static IEnumerable<T> Distinct<T>(this IEnumerable<T> source, Func<T, T, bool> equalityComparer) <br />
{ <br />
int sourceCount = source.Count(); <br />
for (int i = 0; i < sourceCount; i++) <br />
{ <br />
bool found = false; <br />
for (int j = 0; j < i; j++) <br />
if (equalityComparer(source.ElementAt(i), source.ElementAt(j))) // Suivant les cas, il vaut mieux avant la première boucle convertir la source en List<T> <br />
{ <br />
found = true; <br />
break; <br />
} <br />
if (!found) <br />
yield return source.ElementAt(i); <br />
} <br />
} <br />
}
et du coup pour l’utiliser :
var clientsDistincts = (from client in <br />
from c in element.Descendants("Person") <br />
select new { Nom = c.Element("Nom").Value, Prenom = c.Element("Prenom").Value, Ville = c.Element("Ville") == null ? null : c.Element("Ville").Value } <br />
orderby client.Ville descending <br />
select new { client.Nom, client.Prenom, client.Ville }).Distinct((c1, c2) => c1.Nom == c2.Nom && c1.Prenom == c2.Prenom && (c1.Ville == null || c1.Ville == c2.Ville));
Peux-tu m’en dire plus sur ta solution stp. Merci
Pensez au mot-clef « let », ca peut être utile ^^