How to sort a list of names based on it's file data

Viewed 88

I have some .txt files.

The first line of text in each of the files is a number.

I can get a list of all the file names by doing the following:

DirectoryInfo di = new DirectoryInfo(filePath);
FileInfo[] files = di.GetFiles("*.txt");
string[] fileNames = new string[files.Length];

for (int i = 0; i < files.Length; i++)
{
    fileNames[i] = files[i].Name;
}
return fileNames.ToList();

I need to sort fileNames based on the number in these files. From lowest to highest.

There are no duplicate, negative, or decimal numbers (so only positive integers).

Also, you can get the number in the files by doing the following:

foreach (string name in names)
{
    string[] lines = File.ReadAllLines(filePath + name);
    int number = Convert.ToInt32(lines[0]);
}

How do I do this?

3 Answers

I would go like this -- see comments inline


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;                    

public class FileMeta
{
    public string Name {get; set;}

    public string Path {get; set;}
    
    public int Value {get; set;}
    

}


public class Program
{
    public static void Main()
    {
        string dirPath = Path.Combine("c:", "dir1", "dir2");  // USE Path combine, not concatenation
        IEnumerable<FileMeta> metaList = Directory.EnumerateFiles(dirPath, "*.txt", SearchOption.AllDirectories) // USE LINQ to retrieve file path
            .Select(file =>
            {
                int value = 0;
                string fName = Path.GetFileName(file);
                string line = File.ReadLines(file).FirstOrDefault(); // Get a line if exists
                if (!string.IsNullOrWhiteSpace(line))
                    int.TryParse(line.Trim(), out value); // Don't care if parse or not. If not - default 0
                
                
                return new FileMeta(){Name = fName, Path = file, Value = value};
                
            })
            .OrderBy(meta => meta.Value);
        
        // PRINT
        foreach (var meta in metaList)
        {
            Console.WriteLine(@"Full file name: {0}
Name: {1}
Value: {2}", meta.Path, meta.Name, meta.Value);
        }
        
    }
    
    
}

Disclaimer:

  • not tested

  • Done in .net 6

  • Error handling not provided

**!!**And since you're using winforms you can do this with the ListBox. Continue previous code ...

myListbox.DispalyMemeber = "Path";
myListbox.ValueMember = "Value";
myListbox.DataSource = metaList.ToArray();

// And On Selected Index change
var item = myListbox.SelectedItem as FileMeta;
if (item != null)
    MessageBox.Show($"The value in the file '{item.Name}' is '{item.Value}'")

You can use the jagged Array for this.

string[][] arr = new string[names.Length][];

for (int i = 0; i < arr.Length; i++)
{
    string[] lines = File.ReadAllLines(filePath + names[i] + ".txt");
    arr[i] = new string[] { lines[0], names[i]};
}

and then make a list using any sorting method while accessing the first element of each array by arr[j][0].

string[] names = Directory.GetDirectories(filePath).Select(Path.GetFileName).ToArray();
string temp=null;
for(int i=0; i<=names.size(); i++)
 {
 for(int j=i+1; j<=names.size(); j++)
 {
   string[] lines1 = File.ReadAllLines(filePath + names[i] + ".txt");
   int number1 = Convert.ToInt32(lines1[0]);
   string[] lines2 = File.ReadAllLines(filePath + names[j] + ".txt");
   int number2 = Convert.ToInt32(lines2[0]);
   if(number1>number2)
    {
                             
     temp=num[i];
     names[i]=names[j];
     names[j]=temp;
    }
 }
           
}
Related