IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Aplatir une liste générique imbriquée sur plusieurs niveau


Sujet :

C#

  1. #1
    Membre régulier
    Femme Profil pro
    Etudiante en Développement
    Inscrit en
    Avril 2012
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiante en Développement
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 106
    Points : 119
    Points
    119
    Par défaut Aplatir une liste générique imbriquée sur plusieurs niveau
    Bien le bonjour

    Je vous expose mon problème :

    J'ai un modèle de classe, Categorie.
    Chaque catégorie peut avoir des sous-catégorie, représentée par une List<Categorie> en variable privée.

    Voici une version simplifiée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    public class Categorie
    {
            private List<Categorie> listOfCategories;
     
            public string Id { get; set; }
            public string Name { get; set; }
     
     
            public List<Categorie> ListOfCategories
            {
                get
                {
                    return listOfCategories;
                }
            }
    }
    Je voudrais effectuer une recherche sur TOUTES les sous-catégories d'une catégorie définie, mais je ne peux pas savoir à l'avance combien de niveau il y aura (au moins 3 ou 4).

    J'ai essayé avec un SelectMany, mais cela ne m'emmène pas assez loin.

    J'y arrive avec une fonction récursive, mais le temps d'exécution est trooooooop leeeeeeeent

    Je voudrais donc "l'aplatir" pour faire ma recherche en une seule fois sur toutes les catégories enfants

    Existe-t-il une manière plus élégante et plus performante, une requête LINQ peut-être ?

  2. #2
    Membre émérite
    Avatar de azstar
    Homme Profil pro
    Architecte Technique BizTalk/.NET
    Inscrit en
    Juillet 2008
    Messages
    1 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Technique BizTalk/.NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 198
    Points : 2 424
    Points
    2 424
    Par défaut
    Bonjour;

    moi je te conseil pas aller cherche au delà du niveau n+1.
    A mon avis ,dans ton application t' aura besoin de la catégorie et ses enfants.

    Et si nécessaire en cas de besoin ,d'aller chercher les catégories de la catégorie sélectionnée.

    donc essaye de chercher les catégorie et ses enfants. à ce limite t'aura pas une
    méthode lent en exécution mais attention au faite que tu fasses une boucle infini

    category A --->category B -->category A

    ---> : fils de

  3. #3
    Membre régulier
    Femme Profil pro
    Etudiante en Développement
    Inscrit en
    Avril 2012
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiante en Développement
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 106
    Points : 119
    Points
    119
    Par défaut
    J'ai absolument besoin de faire ma recherche sur tous les enfants, à n'importe quel niveau.
    La plupart du temps la catégorie qui matche mes conditions se trouvent dans le niveau le plus bas (4 ou 5) mais elle peut être plus haut.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 436
    Points : 963
    Points
    963
    Par défaut
    Optimise ta requête récursive

    Déjà, pour le débugage, tu as une seule fonction à voir. Si elle fonctionne sur 2 niveaux, elle fonctionnera pour 100 niveaux

    Alors que passer ta liste à plat, à la rigueur avec un dico de clé / valeur pour rechercher sur la valeur et avoir les clés pour retrouver de quels niveaux ils proviennent (il y a différentes manière de faire différente, ceci n'est qu'une idée). Mais tu vas devoir faire une boucle sur n-1 niveau donc déjà pas mal de traitements.

    Ensuite tu vas devoir rechercher dans ta liste puis re matcher et recomposer ton arbo ? Autant directement faire ça dans ta fonction récursive

    J'ai eu un cas similaire, où j'avais décidé de stocker ton objet contenant des listes d'objets qui eux même blablabla ^^ et bien, j'ai finit par reprendre une forme de tree et en optimisant la fonction récursive, j'avais de bien meilleurs résultat et beaucoup moins de code à maintenir !

    Après, comme toujours, ça va dépendre du contexte... (réponse facile.. je sais )

  5. #5
    Membre régulier
    Femme Profil pro
    Etudiante en Développement
    Inscrit en
    Avril 2012
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiante en Développement
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 106
    Points : 119
    Points
    119
    Par défaut
    Merci pour vos réponses

    Quelles sont alors les bonnes pratiques pour que j'optimise ma fonction récursive de la mort qui tue ?

    Je n'en ai pas fait souvent

  6. #6
    Membre émérite
    Avatar de azstar
    Homme Profil pro
    Architecte Technique BizTalk/.NET
    Inscrit en
    Juillet 2008
    Messages
    1 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Technique BizTalk/.NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 198
    Points : 2 424
    Points
    2 424
    Par défaut
    Bonjour

    Si ta pas un nombre très grands des catégories tu peux charger tes cagoteries dans un dictionnary<ID,Category>

    et charger ta table de relation aussi, pour faire toute la traitement en code c# sans faire des requêtes va et vient au SGBD.


    tu peux faire une linqtoObject pour sélectionner tes données depuis ta table de relation pour avoir seulement l ID de tes catégories qui sont déjà chargés dans dictionnary<ID,Category> !!!?

  7. #7
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Juste pour compléter, voici un bon article pour prendre en main SelectMany() : http://blogs.interknowlogy.com/2008/10/10/use-linqs-selectmany-method-to-flatten-collections/

  8. #8
    Membre régulier
    Femme Profil pro
    Etudiante en Développement
    Inscrit en
    Avril 2012
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiante en Développement
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 106
    Points : 119
    Points
    119
    Par défaut
    Merci pour ces précisions

  9. #9
    Membre éclairé
    Homme Profil pro
    Développeur / architecte
    Inscrit en
    Juillet 2009
    Messages
    473
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur / architecte

    Informations forums :
    Inscription : Juillet 2009
    Messages : 473
    Points : 674
    Points
    674
    Par défaut
    Intéressant, j'avais fait qque chose du genre mais en bouclant moi même (fonction récursive) (genre ça).

    En linq, cet exemple a l'air pas mal...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public static IEnumerable<T> Flatten<T>(
        this IEnumerable<MyNode> e,
        Func<T,IEnumerable<T>> f) 
    {
        return e.SelectMany(c => f(c).Flatten(f)).Concat(e);
    }
    Ca donnerait qque chose comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    List<Categorie> racine = //[...] ton code pour obtenir ta liste racine
    IEnumerable<Categorie> liste_applatie = racine.Flatten(racine => racine.ListOfCategories);

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 26/11/2013, 19h34
  2. Réponses: 10
    Dernier message: 18/01/2013, 14h44
  3. [XL-2010] Création d'une liste selon conditions sur plusieurs feuilles
    Par jossuka dans le forum Excel
    Réponses: 2
    Dernier message: 29/10/2012, 09h59
  4. [AC-97] Liste déroulante basée sur plusieurs champs d'une table
    Par docjo dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 02/01/2012, 17h01
  5. fuite de memoire dans une liste de pointeur sur composant
    Par Nicolos_A dans le forum Composants VCL
    Réponses: 2
    Dernier message: 16/12/2004, 08h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo