2 votes

Trier une liste dans laquelle chaque élément contient 2 valeurs

J'ai un fichier texte qui contient des valeurs dans ce format : Time|ID :

180|1
60 |2
120|3

Maintenant, je veux les trier par temps. La sortie devrait également être :

60 |2
120|3
180|1

Comment puis-je résoudre ce problème ? Avec ça :

var path = @"C:\Users\admin\Desktop\test.txt";

List<string> list = File.ReadAllLines(path).ToList();

list.Sort();

for (var i = 0; i < list.Count; i++)
{
   Console.WriteLine(list[i]);
}

Je n'ai pas réussi...

4voto

Mong Zhu Points 15038

3 étapes sont nécessaires pour effectuer le travail :

1) divisé par le séparateur

2) convertir en int car dans une comparaison de chaînes de caractères, un 6 vient après un 1 ou un 10.

3) utiliser OrderBy pour trier votre collection

Voici une solution linq en une seule ligne réalisant les 3 étapes :

list = list.OrderBy(x => Convert.ToInt32(x.Split('|')[0])).ToList();

Explication

x => expression lambda, x désigne un élément unique de votre liste
x.Split('|')[0] divise chaque chaîne et ne prend que la première partie de celle-ci (temps)
Convert.ToInt32(.. convertit l'heure en un nombre afin que la commande soit effectuée comme vous le souhaitez.

list.OrderBy( trie votre collection

EDITAR:

Pour comprendre pourquoi vous avez obtenu le résultat en premier lieu, voici un exemple de comparaison de nombres dans une représentation de chaîne de caractères à l'aide de la fonction CompareTo méthode :

int res = "6".CompareTo("10");

res aura la valeur de 1 (ce qui signifie que 6 est plus grand que 10 ou que 6 suit 10)

Selon la documentation->remarques :

La méthode CompareTo a été conçue principalement pour être utilisée dans des opérations de tri ou d'alphabétisation.

1voto

OmarMuscatello Points 1178

Vous devez analyser chaque ligne du contenu du fichier et obtenir les valeurs sous forme de nombres.

string[] lines = File.ReadAllLines("path");

//                         ID, time
var dict = new Dictionary<int, int>();

// Processing each line of the file content
foreach (var line in lines)
{
    string[] splitted = line.Split('|');

    int time = Convert.ToInt32(splitted[0]);
    int ID = Convert.ToInt32(splitted[1]);

    // Key = ID, Value = Time
    dict.Add(ID, time);
}

var orderedListByID = dict.OrderBy(x => x.Key).ToList();
var orderedListByTime = dict.OrderBy(x => x.Value).ToList();

Notez que j'utilise votre ID référence comme Key de dictionnaire en supposant que ID doit être unique.

Version abrégée

//                                                                      Key = ID                    Value = Time
var orderedListByID = lines.Select(x => x.Split('|')).ToDictionary(x => Convert.ToInt32(x[1]), x => Convert.ToInt32(x[0])).OrderBy(x => x.Key).ToList();
var orderedListByTime = lines.Select(x => x.Split('|')).ToDictionary(x => Convert.ToInt32(x[1]), x => Convert.ToInt32(x[0])).OrderBy(x => x.Value).ToList();

0voto

muntoo Points 4905

Vous devez d'abord les convertir en chiffres. Le tri par chaîne de caractères ne vous donnera pas de résultats significatifs.

times = list.Select(l => l.Split('|')[0]).Select(Int32.Parse);
ids   = list.Select(l => l.Split('|')[1]).Select(Int32.Parse);

pairs = times.Zip(ids, (t, id) => new{Time = t, Id = id})
             .OrderBy(x => x.Time)
             .ToList();

0voto

impidimpi Points 27

Merci à tous, c'est ma Solution :

    var path = @"C:\Users\admin\Desktop\test.txt";

    List<string> list = File.ReadAllLines(path).ToList();
    list = list.OrderBy(x => Convert.ToInt32(x.Split('|')[0])).ToList();

    for(var i = 0; i < list.Count; i++)
    {
        Console.WriteLine(list[i]);
    }

0voto

sunil Points 7
import java.util.ArrayList;  
import java.util.Collections;   
import java.util.List;

public class TestClass {

    public static void main(String[] args) {
    List <LineItem> myList = new ArrayList<LineItem>();     
   myList.add(LineItem.getLineItem(500, 30));    
   myList.add(LineItem.getLineItem(300, 20));    
   myList.add(LineItem.getLineItem(900, 100));  
   System.out.println(myList);

  Collections.sort(myList);

  System.out.println("list after sort");

  System.out.println(myList);

    }

}

class LineItem  implements Comparable<LineItem>{
    int time;
    int id ;
    @Override
    public String toString() {
        return ""+ time + "|"+ id  + "  ";
    }
    @Override
    public int compareTo(LineItem o) {
        return this.time-o.time;
    } 

    public static LineItem getLineItem( int time, int id ){
        LineItem l = new LineItem();
        l.time=time;
        l.id=id;
        return l;
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X