cs_mathmax
Messages postés403Date d'inscriptionvendredi 28 octobre 2005StatutMembreDernière intervention31 août 2008
-
18 avril 2007 à 02:04
cs_mathmax
Messages postés403Date d'inscriptionvendredi 28 octobre 2005StatutMembreDernière intervention31 août 2008
-
30 juin 2007 à 16:53
Bonjour,
Je cherche une manière simple d'indexer une liste d'objets selon certaines propriétés de ces objets. Actuellement, à chaque fois que je veux indexer sur un propriété, je construit un dictionnary<type de ma propriété index, type de mon objet>. Mais je suis obligé de créer un dictionnary pour chaque propriété-index. Je voulais donc savoir si il existe une manière plus simple de procéder ?
C'est très souple, car tu n'as cas désigner un delegate valide pour ta recherche.
Par contre, il doit parcourir toute la liste pour trouver les éléments correspondants, donc tu perdra un peu en efficacité, mais tu gagneras en espace mémoire par rapport au multiples dictionnary. A toi de voir en fonction de ce que tu fais ce qui est le plus efficace.
cs_mathmax
Messages postés403Date d'inscriptionvendredi 28 octobre 2005StatutMembreDernière intervention31 août 2008 18 avril 2007 à 12:00
Merci SharpMao, je connaissais Findall, mais je recherche quelque chose qui fait des recherches dichotomiques sur les propriété des mes objets.
DeAtHCrAsH, je ne vois pas trop ce que tu veux dire. Je cherche un moyen de définir des indexeurs pour une collection,
qui ne parcourent pas toutes les propriétés avant de renvoyer l'objet
voulu. Connais-tu un moyen plus efficace que de créer un dictionary pour chaque indexeur ?
leprov
Messages postés1160Date d'inscriptionvendredi 23 juillet 2004StatutMembreDernière intervention21 octobre 201017 19 avril 2007 à 14:23
Effectivement autant pour moi, j'ai cru que tu parlais de DictionaryEntry -et donc que tu réinventais la roue ^^ -(un peu a l'ouest)...
Et en effet, je ne vois pas de meilleur solution que les dictionnary. Si tes types, que ce soit clés ou valeur, sont des types référence, je ne vois pas le soucis, que ce soit en temps de traitement, simplicité du code, ou meme en terme de charge mémoire, tu fera pas beaucoup mieux (ou alors faudra sacrifier un des paramètres ci dessus ^^).
cs_mathmax
Messages postés403Date d'inscriptionvendredi 28 octobre 2005StatutMembreDernière intervention31 août 2008 19 avril 2007 à 16:12
En fait je pense qu'avec linq on aura la solution à ce problème. On pourra séléctionner dans une collection d'objet, seulement ceux dont une propriété vaut telle valeur. Par contre, en terme de performance, je ne sais pas ce qui se passe derrière une requête linq. Est-ce que les propriétés sont toutes parcourues (et donc celà revientà utiliser une boucle foreach avec un break quand on a trouvé l'objet) ou bien la recherche sera t-elle comparable à celle réalisée par un dictionary ?
cs_mathmax
Messages postés403Date d'inscriptionvendredi 28 octobre 2005StatutMembreDernière intervention31 août 2008 30 juin 2007 à 16:53
J'ai écrit une méthode d'extension qui permet de faire une recherche dichotomique dans une liste d'objet triée selon une propriétée. Je me damande pourquoi une telle fonction n'existe pas en natif dans le framework. Quand on a une liste très longue, pour peu qu'elle soit triée, la recherche est bien plus rapide.
Voici le code :
public static class ListExtensions
{
public delegate IComparable dlgProperty<S>(S o);
public static S Find<S>(this List<S> list, dlgProperty<S> dlg, IComparable value) where S : class
{
int left = 0;
int right = list.Count;
int middle;
while ((middle = (int)Math.Floor((decimal)((right - left) / 2) + left))!=left)
{
S current = list[middle];
switch (dlg(current).CompareTo(value))
{
case (1):
right = middle;
break;
case (-1):
left = middle;
break;
default:
return current;
}
}
return null;
}
}
Et voici de quoi la tester :
class Program
{
static void Main(string[] args)
{
List<Test> tests = new List<Test>();
for (int i = 0; i < 9365220; i++)
tests.Add(new Test(i.ToString()));
Stopwatch sw = new Stopwatch( );
sw.Reset();
sw.Start();
//Test test = tests.Find(y=>y.Value, "7023915");
Test test = tests.Find(y=>y.Value == "7023915");
sw.Stop();
Console.WriteLine("Temps pour la recherche {0} ms",sw.ElapsedMilliseconds);
Console.WriteLine("Valeur trouvée : {0}", test.Value);
}
}
public class Test
{
private string _Value;
public Test(string value)
{
_Value = value;
}
public string Value
{
get { return _Value; }
set { _Value = value; }
}
}
public static class ListExtensions
{
public delegate IComparable dlgProperty<S>(S o);
public static S Find<S>(this List<S> list, dlgProperty<S> dlg, IComparable value) where S : class
{
int left = 0;
int right = list.Count;
int middle;
while ((middle = (int)Math.Floor((decimal)((right - left) / 2) + left))!=left)
{
S current = list[middle];
switch (dlg(current).CompareTo(value))
{
case (1):
right = middle;
break;
case (-1):
left = middle;
break;
default:
return current;
}
}
return null;
}
}