0
votes

Lors du tri d'une liste par un champ Int, pouvez-vous trier 310 entre 41 et 39?

J'ai un alist d'objets que je trie par leur champ d'identification, mais les ID sont générés pour aller 38, 39, 310, 41, 42, etc. Y a-t-il une fonction LINQ pour gérer ce genre de chose?

J'ai essayé une boucle post-tri, de me déplacer autour des objets de ma liste, mais c'est une solution de performance pour être une solution viable. J'ai également essayé d'échanger les identifiants de 310 à 40 lorsque je les récupèrent et que je les retouche après le tri, mais on m'a dit que cela n'était pas non viable, au cas où ils commenceraient 39, 310, 40 à l'avenir. J'ai également demandé à l'autre Dev s'il pouvait changer la génération d'identité pour aller de 39 à 40, il m'a dit que c'est un code hérité qu'il ne veut pas toucher. xxx

Le résultat actuel ressemble à: 310, 210, 110, 39, 38, etc

J'aimerais ressembler à: 42, 41, 310, 39, 38, ..., 31, 210, 29, etc


9 commentaires

"J'aimerais avoir l'air de ressembler à: 42, 41, 310, 39, 38, ..., 31, 210, 29, etc" - qui ressemble à très personnalisé Tri de la logique. Donc, non, ni Linq ni rien d'autre ne vont avoir une fonction qui définit déjà votre logique de tri personnalisée . Vous allez devoir définir cette logique et écrire du code pour cela.


Supposons que je vous donne tout deux chiffres, x et y. Veuillez décrire pour moi une règle simple qui choisit exactement l'une des trois options: elles sont égales, X passe avant y dans la commande, ou x va après Y dans la commande. Si vous pouvez le faire, le problème peut être résolu assez facilement, mais je ne comprends pas exactement ce que votre règle est.


Curieux quand la séquence est 308,309, ..... quelle serait la prochaine?


308 309 3100,40,


"Si elles commençaient à aller 39, 310, 40" - mais à que pointez, vous aurez des codages ambiguës que vous n'avez pas encore beaucoup plus de considération pour que cela devrait être autorisé .


Vous pouvez .tostring () et cela fonctionnera,


@fhnaseer: le tri par valeurs de chaîne triera 310 à côté de 31, pas à côté de 39.


@fhnaseer nouveau [] {42, 41, 310, 39, 38} .orderde (i => i.tostring ()) produit 310, 38, 39, 41, 42


@ERICLIPPERT YEAH, je crois que vous devez écrire votre propre logique personnalisée pour la classe. Mettre en œuvre icomarer peut-être,


4 Réponses :


0
votes

Donc, si le nombre est exactement divisible par 10, nous devons diviser par 100, ajouter 1 et multiplier par 10 pour récupérer la valeur "réelle" qui triera naturellement 1 : Xxx

Je suppose numéro est int et permet aux règles de division entier de "se débarrasser" du pesky 0.1 Après la division.

1 c'est-à-dire que 310 doit être traité comme 40, 510 doit être traité comme 60, etc.


5 commentaires

Et s'il y a des chiffres comme 3100


Il n'est pas clair de la question initiale que faire si 311 est dans la liste; Votre algorithme ne considère pas cela.


@PeciousBetine - Si le modèle de numéro se répète comme indiqué dans la question, nous nous attendions au numéro suivant après 3099 pour être 30910 , suivi de 3101 < / code>. Nous ne nous attendions jamais à voir un 3100 car des numéros qui doivent avoir un 0 dans la position des parts apparemment ont 10 dans la position "Unités" et avoir une dizaine à chiffrer un plus bas que prévu.


De plus, je ne comprends pas comment votre algorithme fonctionne si, disons, 310 et 40 sont tous deux dans la liste. La clé de tri pour 310 sera de 40, et la clé de tri de 40 sera de 10, alors cela ne signifie pas que 310 sera à gauche de 40?


@ERIFLIPPERT - J'avais initialement manqué qu'ils spéculaient que, à l'avenir, ils peuvent avoir à la fois 310 et 40 être possible. Mais comme je l'ai signalé, cela signifie qu'ils commencent à avoir des codages ambigus. Cette réponse aborde les codages qu'ils ont en ce moment mais pas cet État futur.



3
votes

Il me semble que vous essayez simplement de prioriser le premier numéro dans l'entier, avant le numéro dans son ensemble. Si oui, peut-être que cela fonctionnera pour vous?

public static class IntExtensions
{
    public static int Length(this int value)
    {
        value = Math.Abs(value);
        if (value < 10) return 1;
        if (value < 100) return 2;
        if (value < 1000) return 3;
        if (value < 10000) return 4;
        if (value < 100000) return 5;
        if (value < 1000000) return 6;
        if (value < 10000000) return 7;
        if (value < 100000000) return 8;
        if (value < 1000000000) return 9;
        return 10;
    }
}


1 commentaires

Cela a fonctionné parfaitement, merci. À moins que quelque chose de changement drastique, il ne devrait jamais y avoir plus de 60 de ces objets par liste, mais si ce jour arrive, merci pour le conseil là-bas.



-1
votes

Je recommanderais de diviser les numéros dans des tableaux de caractères et de faire un tri initial par le premier caractère.

Paysez ensuite les caractères restants sur INT pour le tri décroissant. Comme si xxx


4 commentaires

Votre premier OrderBy devrait être probablement OrderByDescendant . FYI, il n'est pas nécessaire d'appeler Tokararray ().


Je ne comprends pas quelle fonction de Tokararray est ici; peux-tu expliquer? Si vous avez une chaîne et que vous voulez le premier caractère, pourquoi pas seulement dire x [0] ?


Je ne comprends pas non plus pourquoi vous retirez le premier caractère dans le puis . Sûrement si nous avons "310" et "39", alors nous pouvons simplement dire que 310 est supérieur à 39; Nous n'avons pas à comprendre que de comprendre en notant que 10 est supérieur à 9.


Mes connaissances de la syntaxe ne sont pas très avancées, il existe donc probablement une meilleure façon plus vif lancée. L'idée est le tri par premier caractère, puis la valeur restante. Je suis un utilisateur C # autodidacte, je ne prétends pas être un promoteur d'expert. J'ai pensé que cela m'aiderait à apprendre



1
votes

Vous pouvez utiliser un icomparer code> pour trier la liste directement.

data.Sort(new LegacyIdDescendingComparer());


0 commentaires