7
votes

Recherche de liste hiérarchique

J'ai une classe simple définie comme suit:

private IndexEntry GetHighScoreEntry(IEnumerable<IndexEntry> entryList)
{
    IndexEntry result = null;
    IndexEntry recursiveResult = null;
    foreach (IndexEntry currentEntry in entryList)
    {
        if (currentEntry.HighScore)
        {
            result = currentEntry;
            break;  //Don't need to look anymore, we found our highscore.;
        }
        else
        {
            if ((currentEntry.SubEntries == null) || (currentEntry.SubEntries.Count < 1))
            {
                continue;
            }
            else
            {
                recursiveResult = GetHighScoreEntry(currentEntry.SubEntries);
                if (recursiveResult == null)
                    continue;
                    result = recursiveResult;
                break;
            }
        }
    }
    return result;
}


0 commentaires

3 Réponses :


0
votes

Vous pouvez considérablement réduire votre recherche avec une expression de Lambda quelque chose comme: xxx pré>

mise à jour b> p>

réellement la première solution ne sera pas traverser correctement. Je ne pense pas qu'il y ait une solution lambda uniquement à cela, vous devrez faire une forme de fonction récursive. En haut de ma tête, ce qui suit fonctionnerait, comment cela ferait la performance sage, je suis incertain: P>

public IndexEntry FindHighScore(List<IndexEntry> entries)
{
    var highScore = GetHighScore(entries);
    if (highScore == null)
    {
        // give me only entries that contain sub-entries
        var entriesWithSub = entries.Where(e => e.SubEntries != null);
        foreach (var e in entriesWithSub)
        {
            highScore = FindHighScore(e.SubEntries);
            if (highScore != null)
                return highScore;
        }
    }
    return highScore;
}

private IndexEntry GetHighScore(List<IndexEntry> entries)
{
    return entries.FirstOrDefault(IE => IE.HighScore);
}


2 commentaires

James. Merci. Je m'essayais en fait d'utiliser une combinaison de solutions de votre et _rusty pour obtenir ce dont j'ai besoin. Je vais essayer cela et faire rapport sur la performance.


Pour être honnête, les deux réponses ne sont pas vraiment aussi éloignées de chaque autre que ce soit vraiment que l'on vous donne la meilleure performance. Même les repasser contre votre solution actuelle.



2
votes

Recursion est votre ami ici. XXX


1 commentaires

(Bien sûr, cela pourrait utiliser une vérification nulle dans les bons endroits, mais cet exercice est laissé pour le lecteur;))



10
votes

Toutes les solutions postées jusqu'à présent sont spécialisées - elles ne sont ni génériques ni générales, et donc, la prochaine fois que vous avez une liste hiérarchique, vous devrez classer une nouvelle solution. Yuck.

Voici une solution générique générique qui fonctionnera pour tous vos besoins hiérarchiques: p> xxx pré>

Voici comment vous l'utiliseriez: P>

myList.Flatten(i => i.SubEntries).FirstOrDefault(i => i.HighScore);


7 commentaires

Juda. J'aime votre idée générale, mais je ne suis pas assez à l'aise en C # pour résoudre un problème avec votre code. Lorsque j'essaie de compléter votre code, j'obtiens l'erreur suivante - le corps de 'ienumérablementextensions.flatten (System.Collections.Cénéforce .ienceréra , system.func >) 'ne peut pas être un bloc d'itérateur car "void" n'est pas un type d'interface Itérateur.


Cette erreur me suggère que vous devez retourner un type (iEnumerable peut-être?), Puis travaillez avec cet article?


@Steve, vous êtes correct, sa méthode doit avoir un type de retour d'iEnumerable pour le rendement au travail.


Woops, oui, il devrait retourner iEnumerable . J'ai réparé cela dans le poteau.


Donc, juste un commentaire rapide pour ceux qui sont intéressés. Cette version semble me donner environ 20% de performance de performance en utilisant un type de récursivité.


Juda Himango, veuillez corriger la source C # texte de votre réponse pour corriger l'erreur ci-dessus à ce sujet à ce sujet que la méthode doit avoir un type de retour d'Ienumerable pour le rendement au travail.


@ Dr.Doog j'ai déjà réparé cela il y a 6 ans. Voir le commentaire ci-dessus où j'ai dit: "Woops, oui, il devrait retourner ienumerable . J'ai réparé cela dans le poteau."