Search code examples
c#randomforeachrenamegenerate

Rename with random numbers


I was trying to make smth like this... Basically im trying to shuffle music by their names. Everything works nicely, but i was wondering if theres a way for tihs random funcion not to repeat same numbers?

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
     button1.Enabled = true;

     DirectoryInfo dir = new DirectoryInfo(comboBox1.SelectedItem.ToString());
     count = dir.GetFiles().Length;
     label3.Text = "Files loaded: " + count.ToString();
}
private void button1_Click(object sender, EventArgs e)
{

     DirectoryInfo d = new DirectoryInfo(comboBox1.SelectedItem.ToString());
     FileInfo[] infos = d.GetFiles("*.mp3");
     int i = 1;

     foreach (FileInfo f in infos)
     {
         File.Move(f.FullName, Path.Combine(f.DirectoryName, i + ". " + f.Name));
         i = rnd.Next(1, count+1);
     }
}

Solution

  • You could try something like this:

    string path = comboBox1.SelectedItem.ToString();
    
    var files = Directory.GetFiles(path, "*.mp3");
    // Create list of shuffled numbers
    var shuffledNumbers = Enumerable.Range(1, files.Length).ToArray().OrderBy(i => Guid.NewGuid());
    // put the shuffled numbers into a stack
    var indexes = new Stack<int>(shuffledNumbers);
    foreach(var file in files) {
        // extract first item from the stack
        var index = indexes.Pop();
        // move file
        File.Move(file, Path.Combine(path, $"{index}. {Path.GetFileName(file)}"));
    }
    

    Basically I shuffle an array of sequential numbers using Guid.NewGuid as a order key.

    Every time OrderBy will compare two items of the array, it will get a different, totally random value.

    Using a Stack allows me to just pop the next number without having to use an indexer variable (but it's totally fine if you prefer that way).