Bagaimana cara mengurutkan string menurut abjad sambil menghitung nilai saat string berbentuk numerik?

100

Saya mencoba mengurutkan deretan angka yang merupakan string dan saya ingin mereka mengurutkan secara numerik.

Hasil tangkapannya adalah saya tidak bisa mengubah angka menjadi int .

Ini kodenya:

string[] things= new string[] { "105", "101", "102", "103", "90" };

foreach (var thing in things.OrderBy(x => x))
{
    Console.WriteLine(thing);
}

keluaran: 101, 102, 103, 105, 90

Saya suka: 90, 101, 102, 103, 105

EDIT: Outputnya tidak boleh 090, 101, 102 ...

Memperbarui contoh kode menjadi "benda" bukan "ukuran". Array bisa menjadi seperti ini:

string[] things= new string[] { "paul", "bob", "lauren", "007", "90" };

Itu berarti perlu diurutkan menurut abjad dan nomor:

007, 90, bob, lauren, paul

sf.
sumber
8
Mengapa Anda tidak dapat mengubahnya menjadi int?
Femaref
1
"ukuran" bisa menjadi sesuatu yang lain seperti "nama". Contoh kode baru saja disederhanakan.
sf.
2
Apakah ada di antara angkanya yang negatif? Apakah semuanya akan menjadi bilangan bulat? Berapa kisaran bilangan bulatnya?
Eric Lippert
"benda" bisa berupa string apa pun. Saya ingin daftar tersebut diurutkan secara logis untuk orang yang tidak melek komputer. Angka negatif harus sebelum postive. Dalam hal panjang string, tidak lebih dari 100 karakter.
sf.
5
Seberapa jauh Anda ingin pergi? Haruskah image10datang setelah image2? Haruskah Januarydatang sebelumnya February?
svick

Jawaban:

104

Meneruskan pembanding kustom ke OrderBy. Enumerable.OrderBy akan membiarkan Anda menentukan pembanding yang Anda suka.

Ini adalah salah satu cara untuk melakukannya:

void Main()
{
    string[] things = new string[] { "paul", "bob", "lauren", "007", "90", "101"};

    foreach (var thing in things.OrderBy(x => x, new SemiNumericComparer()))
    {    
        Console.WriteLine(thing);
    }
}


public class SemiNumericComparer: IComparer<string>
{
    /// <summary>
    /// Method to determine if a string is a number
    /// </summary>
    /// <param name="value">String to test</param>
    /// <returns>True if numeric</returns>
    public static bool IsNumeric(string value)
    {
        return int.TryParse(value, out _);
    }

    /// <inheritdoc />
    public int Compare(string s1, string s2)
    {
        const int S1GreaterThanS2 = 1;
        const int S2GreaterThanS1 = -1;

        var IsNumeric1 = IsNumeric(s1);
        var IsNumeric2 = IsNumeric(s2);

        if (IsNumeric1 && IsNumeric2)
        {
            var i1 = Convert.ToInt32(s1);
            var i2 = Convert.ToInt32(s2);

            if (i1 > i2)
            {
                return S1GreaterThanS2;
            }

            if (i1 < i2)
            {
                return S2GreaterThanS1;
            }

            return 0;
        }

        if (IsNumeric1)
        {
            return S2GreaterThanS1;
        }

        if (IsNumeric2)
        {
            return S1GreaterThanS2;
        }

        return string.Compare(s1, s2, true, CultureInfo.InvariantCulture);
    }
}
Jeff Paulsen
sumber
1
Untuk masukan yang diberikan, ini menghasilkan hasil yang sama seperti jawaban Recursive, yang melibatkan PadLeft (). Saya berasumsi bahwa masukan Anda sebenarnya lebih kompleks daripada yang ditunjukkan contoh ini, dalam hal ini pembanding khusus adalah cara yang tepat.
Jeff Paulsen
Bersulang. Solusi ini berfungsi dan sepertinya cara yang mudah dibaca dan bersih untuk diterapkan. 1 untuk menunjukkan kepada saya bahwa Anda dapat menggunakan IComparer di OrderBy :)
sf.
17
The IsNumericMetode buruk, Exception didorong coding selalu buruk. Gunakan int.TryParsesebagai gantinya. Coba kode Anda dengan daftar besar dan itu akan berlangsung selamanya.
Nean Der Thal
Jika bermanfaat, saya menambahkan ekstensi ke versi ini di sini yang menambahkan dukungan untuk pengurutan dengan kata-kata. Untuk kebutuhan saya, membagi spasi sudah cukup, dan saya tidak perlu terlalu khawatir tentang kata-kata yang menggunakan campuran (misalnya test12 vs test3),
matt.bungard
@NeanDerThal Saya cukup yakin ini hanya lambat / buruk menangani banyak pengecualian dalam satu lingkaran, jika Anda sedang men-debug atau mengakses objek Pengecualian.
Kelly Elton
90

Cukup pad dengan nol dengan panjang yang sama:

int maxlen = sizes.Max(x => x.Length);
var result = sizes.OrderBy(x => x.PadLeft(maxlen, '0'));
rekursif
sumber
+1 untuk solusi sederhana, rewel akan (sudah selesai di edit, bagus)
Marino Šimić
Ide bagus, tetapi hasil berikutnya adalah saya perlu membagi nilai-nilai ini sehingga "90" harus menjadi "90", bukan "090"
sf.
6
@sf: Cobalah, Anda mungkin menyukai hasilnya. Ingat, kunci pesanan bukanlah hal yang dipesan. Jika saya mengatakan memesan daftar pelanggan dengan nama belakang, maka saya mendapatkan daftar pelanggan, bukan daftar nama belakang. Jika Anda mengatakan untuk mengurutkan daftar string dengan string yang diubah maka hasilnya adalah daftar string asli yang diurutkan, bukan string yang diubah.
Eric Lippert
Saya harus menambahkan "ukuran = ukuran.OrderBy (...)" agar ini berfungsi. Apakah itu normal atau haruskah jawabannya diedit?
gorgabal
1
@gorgabal: Secara umum penugasan ulang ke sizesjuga tidak akan berhasil, karena hasilnya adalah tipe yang berbeda. Jawabannya agak singkat, di baris kedua menunjukkan hasil sebagai ekspresi, tetapi terserah pembaca untuk melakukan sesuatu dengannya. Saya telah menambahkan tugas variabel lain untuk membuatnya lebih jelas.
rekursif
74

Dan, bagaimana dengan ini ...

string[] sizes = new string[] { "105", "101", "102", "103", "90" };

var size = from x in sizes
           orderby x.Length, x
           select x;

foreach (var p in size)
{
    Console.WriteLine(p);
}
shenhengbin.dll
sumber
hehe, saya sangat suka yang ini - sangat pintar. Maaf jika saya tidak memberikan set lengkap data awal
sf.
3
Ini seperti opsi pad di atas hanya IMO yang jauh lebih baik.
dudeNumber4
3
var size = size.OrderBy (x => x.Length) .ThenBy (x => x);
Phillip Davis
1
Tapi ini akan bercampur string abjad seperti ini: "b", "ab", "101", "103", "bob", "abcd".
Andrew
67

Nilai adalah string

List = List.OrderBy(c => c.Value.Length).ThenBy(c => c.Value).ToList();

Bekerja

Gema
sumber
2
Jawaban ini adalah favorit saya.
LacOniC
2
Terima kasih, saya baru saja menemukan bahwa keluar dari metode "ThenBy".
ganchito55
Ini berfungsi dengan baik untuk kasus penggunaan saya, di mana input dalam format barustring[] { "Object 1", "Object 9", "Object 14" }
thelem
2
Ini jawaban terbaik. Itu berhasil dan merupakan pembelajaran yang baik. Terima kasih !!
Biasa
1
Tapi ini akan bercampur string abjad seperti ini: "b", "ab", "101", "103", "bob", "abcd".
Andrew
13

Ada fungsi asli di windows StrCmpLogicalWyang akan membandingkan angka string sebagai angka, bukan huruf. Sangat mudah untuk membuat pembanding yang memanggil fungsi itu dan menggunakannya untuk perbandingannya.

public class StrCmpLogicalComparer : Comparer<string>
{
    [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
    private static extern int StrCmpLogicalW(string x, string y);

    public override int Compare(string x, string y)
    {
        return StrCmpLogicalW(x, y);
    }
}

Ia bahkan bekerja pada string yang memiliki teks dan angka. Berikut adalah contoh program yang akan menunjukkan perbedaan antara pengurutan default dan StrCmpLogicalWpengurutan

class Program
{
    static void Main()
    {
        List<string> items = new List<string>()
        {
            "Example1.txt", "Example2.txt", "Example3.txt", "Example4.txt", "Example5.txt", "Example6.txt", "Example7.txt", "Example8.txt", "Example9.txt", "Example10.txt",
            "Example11.txt", "Example12.txt", "Example13.txt", "Example14.txt", "Example15.txt", "Example16.txt", "Example17.txt", "Example18.txt", "Example19.txt", "Example20.txt"
        };

        items.Sort();

        foreach (var item in items)
        {
            Console.WriteLine(item);
        }

        Console.WriteLine();

        items.Sort(new StrCmpLogicalComparer());

        foreach (var item in items)
        {
            Console.WriteLine(item);
        }
        Console.ReadLine();
    }
}

keluaran yang mana

Example1.txt
Example10.txt
Example11.txt
Example12.txt
Example13.txt
Example14.txt
Example15.txt
Example16.txt
Example17.txt
Example18.txt
Example19.txt
Example2.txt
Example20.txt
Example3.txt
Example4.txt
Example5.txt
Example6.txt
Example7.txt
Example8.txt
Example9.txt

Example1.txt
Example2.txt
Example3.txt
Example4.txt
Example5.txt
Example6.txt
Example7.txt
Example8.txt
Example9.txt
Example10.txt
Example11.txt
Example12.txt
Example13.txt
Example14.txt
Example15.txt
Example16.txt
Example17.txt
Example18.txt
Example19.txt
Example20.txt
Scott Chamberlain
sumber
Saya berharap lebih mudah menggunakan pustaka sistem di C #
Kyle Delaney
Ini akan menjadi sempurna, tetapi sayangnya tidak menangani angka negatif. -1 0 10 2diurutkan sebagai0 -1 2 10
nphx
5

coba ini

sizes.OrderBy(x => Convert.ToInt32(x)).ToList<string>();

Catatan: ini akan membantu ketika semua string dapat diubah menjadi int .....

Pranay Rana
sumber
1
semacam ini mengubah string menjadi int.
Femaref
1
"ukuran" juga bisa non numerik
sf.
Untuk "LINQ to SQL" jangan lupa ToList()before =>sizes.ToList().OrderBy(x => Convert.ToInt32(x))
A. Morel
5

Saya kira ini akan jauh lebih baik jika memiliki beberapa angka dalam string. Semoga bisa membantu.

PS: Saya tidak yakin tentang kinerja atau nilai string yang rumit tetapi bekerja dengan baik seperti ini:

lorem ipsum
lorem ipsum 1
lorem ipsum 2
lorem ipsum 3
...
lorem ipsum 20
lorem ipsum 21

public class SemiNumericComparer : IComparer<string>
{
    public int Compare(string s1, string s2)
    {
        int s1r, s2r;
        var s1n = IsNumeric(s1, out s1r);
        var s2n = IsNumeric(s2, out s2r);

        if (s1n && s2n) return s1r - s2r;
        else if (s1n) return -1;
        else if (s2n) return 1;

        var num1 = Regex.Match(s1, @"\d+$");
        var num2 = Regex.Match(s2, @"\d+$");

        var onlyString1 = s1.Remove(num1.Index, num1.Length);
        var onlyString2 = s2.Remove(num2.Index, num2.Length);

        if (onlyString1 == onlyString2)
        {
            if (num1.Success && num2.Success) return Convert.ToInt32(num1.Value) - Convert.ToInt32(num2.Value);
            else if (num1.Success) return 1;
            else if (num2.Success) return -1;
        }

        return string.Compare(s1, s2, true);
    }

    public bool IsNumeric(string value, out int result)
    {
        return int.TryParse(value, out result);
    }
}
Cansın Şenalioğlu
sumber
Persis apa yang saya cari. Terima kasih!
klugerama
4

Kamu bilang kamu tidak bisa mengubah angka menjadi int karena array bisa berisi elemen yang tidak bisa diubah menjadi int, tapi tidak ada salahnya mencoba:

string[] things = new string[] { "105", "101", "102", "103", "90", "paul", "bob", "lauren", "007", "90" };
Array.Sort(things, CompareThings);

foreach (var thing in things)
    Debug.WriteLine(thing);

Kemudian bandingkan seperti ini:

private static int CompareThings(string x, string y)
{
    int intX, intY;
    if (int.TryParse(x, out intX) && int.TryParse(y, out intY))
        return intX.CompareTo(intY);

    return x.CompareTo(y);
}

Keluaran: 007, 90, 90, 101, 102, 103, 105, bob, lauren, paul

Ulf Kristiansen
sumber
Btw, saya menggunakan Array.Sort untuk kesederhanaan, tetapi Anda dapat menggunakan logika yang sama di IComparer dan menggunakan OrderBy.
Ulf Kristiansen
Solusi ini tampaknya lebih cepat daripada menggunakan IComparer (pendapat saya). Hasil 15000 dan saya merasa ini menghasilkan tentang perbedaan kedua.
Jason Foglia
3

Ini sepertinya permintaan yang aneh dan pantas mendapatkan solusi yang aneh:

string[] sizes = new string[] { "105", "101", "102", "103", "90" };

foreach (var size in sizes.OrderBy(x => {
    double sum = 0;
    int position = 0;
    foreach (char c in x.ToCharArray().Reverse()) {
        sum += (c - 48) * (int)(Math.Pow(10,position));
        position++;
    }
    return sum;
}))

{
    Console.WriteLine(size);
}
Marino Šimić
sumber
Maksud saya, tentu saja 0x30. Selain itu, larik masih dapat berisi string non-numerik, yang solusinya akan memberikan hasil yang menarik.
Femaref
Dan perhatikan bahwa -48 atau tidak sama sekali tidak mengubah apa pun, kita dapat langsung menggunakan nilai integer dari char, jadi hapus -48 jika itu mengganggu Anda ...
Marino Šimić
Nilai karakternya adalah 0x30, jika Anda mengubahnya menjadi int, nilainya akan tetap 0x30, yang bukan merupakan angka 0.
Femaref
Satu-satunya hal yang diubah menjadi bilangan bulat adalah dobel yang dikembalikan dari Math.Pow
Marino Šimić
femaref tidak masalah apakah itu nol atau tidak, sistem dekadik mengurusnya, itu bisa menjadi Đ jika Anda mau, satu-satunya hal yang penting bahwa angka-angka itu dalam urutan menaik dalam set karakter, dan itu kurang dari 10
Marino Šimić
3

Situs ini membahas pengurutan alfanumerik dan akan mengurutkan angka dalam arti logis, bukan dalam pengertian ASCII. Ini juga memperhitungkan alfa di sekitarnya:

http://www.dotnetperls.com/alphanumeric-sorting

CONTOH:

  • C: /TestB/333.jpg
  • 11
  • C: /TestB/33.jpg
  • 1
  • C: /TestA/111.jpg
  • 111F
  • C: /TestA/11.jpg
  • 2
  • C: /TestA/1.jpg
  • 111D
  • 22
  • 111Z
  • C: /TestB/03.jpg

  • 1
  • 2
  • 11
  • 22
  • 111D
  • 111F
  • 111Z
  • C: /TestA/1.jpg
  • C: /TestA/11.jpg
  • C: /TestA/111.jpg
  • C: /TestB/03.jpg
  • C: /TestB/33.jpg
  • C: /TestB/333.jpg

Kodenya adalah sebagai berikut:

class Program
{
    static void Main(string[] args)
    {
        var arr = new string[]
        {
           "C:/TestB/333.jpg",
           "11",
           "C:/TestB/33.jpg",
           "1",
           "C:/TestA/111.jpg",
           "111F",
           "C:/TestA/11.jpg",
           "2",
           "C:/TestA/1.jpg",
           "111D",
           "22",
           "111Z",
           "C:/TestB/03.jpg"
        };
        Array.Sort(arr, new AlphaNumericComparer());
        foreach(var e in arr) {
            Console.WriteLine(e);
        }
    }
}

public class AlphaNumericComparer : IComparer
{
    public int Compare(object x, object y)
    {
        string s1 = x as string;
        if (s1 == null)
        {
            return 0;
        }
        string s2 = y as string;
        if (s2 == null)
        {
            return 0;
        }

        int len1 = s1.Length;
        int len2 = s2.Length;
        int marker1 = 0;
        int marker2 = 0;

        // Walk through two the strings with two markers.
        while (marker1 < len1 && marker2 < len2)
        {
            char ch1 = s1[marker1];
            char ch2 = s2[marker2];

            // Some buffers we can build up characters in for each chunk.
            char[] space1 = new char[len1];
            int loc1 = 0;
            char[] space2 = new char[len2];
            int loc2 = 0;

            // Walk through all following characters that are digits or
            // characters in BOTH strings starting at the appropriate marker.
            // Collect char arrays.
            do
            {
                space1[loc1++] = ch1;
                marker1++;

                if (marker1 < len1)
                {
                    ch1 = s1[marker1];
                }
                else
                {
                    break;
                }
            } while (char.IsDigit(ch1) == char.IsDigit(space1[0]));

            do
            {
                space2[loc2++] = ch2;
                marker2++;

                if (marker2 < len2)
                {
                    ch2 = s2[marker2];
                }
                else
                {
                    break;
                }
            } while (char.IsDigit(ch2) == char.IsDigit(space2[0]));

            // If we have collected numbers, compare them numerically.
            // Otherwise, if we have strings, compare them alphabetically.
            string str1 = new string(space1);
            string str2 = new string(space2);

            int result;

            if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
            {
                int thisNumericChunk = int.Parse(str1);
                int thatNumericChunk = int.Parse(str2);
                result = thisNumericChunk.CompareTo(thatNumericChunk);
            }
            else
            {
                result = str1.CompareTo(str2);
            }

            if (result != 0)
            {
                return result;
            }
        }
        return len1 - len2;
    }
}
Chad Kuehn
sumber
2

Jawaban yang diberikan oleh Jeff Paulsen benar tetapi Comprarerdapat disederhanakan menjadi ini:

public class SemiNumericComparer: IComparer<string>
{
    public int Compare(string s1, string s2)
    {
        if (IsNumeric(s1) && IsNumeric(s2))
          return Convert.ToInt32(s1) - Convert.ToInt32(s2)

        if (IsNumeric(s1) && !IsNumeric(s2))
            return -1;

        if (!IsNumeric(s1) && IsNumeric(s2))
            return 1;

        return string.Compare(s1, s2, true);
    }

    public static bool IsNumeric(object value)
    {
        int result;
        return Int32.TryParse(value, out result);
    }
}

Ini berfungsi karena satu-satunya hal yang diperiksa untuk hasil Comparer adalah jika hasilnya lebih besar, lebih kecil atau sama dengan nol. Seseorang dapat dengan mudah mengurangi nilai dari yang lain dan tidak harus menangani nilai yang dikembalikan.

Juga IsNumericmetode ini tidak harus menggunakan try-block dan bisa mendapatkan keuntunganTryParse .

Dan bagi mereka yang tidak yakin: Pembanding ini akan mengurutkan nilai sehingga nilai non numerik selalu ditambahkan ke akhir daftar. Jika seseorang menginginkannya di awal, ifblok kedua dan ketiga harus ditukar.

kacang
sumber
Karena memanggil metode TryParse mungkin memiliki beberapa overhead, saya akan menyimpan nilai isNumeric untuk s1 dan s2 ke dalam nilai boolean terlebih dahulu dan melakukan perbandingan pada nilai tersebut. Dengan cara ini mereka tidak dievaluasi berkali-kali.
Optavius
1

Coba ini :

string[] things= new string[] { "105", "101", "102", "103", "90" };

int tmpNumber;

foreach (var thing in (things.Where(xx => int.TryParse(xx, out tmpNumber)).OrderBy(xx =>     int.Parse(xx))).Concat(things.Where(xx => !int.TryParse(xx, out tmpNumber)).OrderBy(xx => xx)))
{
    Console.WriteLine(thing);
}
TMAmine
sumber
1
public class NaturalSort: IComparer<string>
{
          [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
          public static extern int StrCmpLogicalW(string x, string y);

          public int Compare(string x, string y)
          {
                 return StrCmpLogicalW(x, y);
          }
}

arr = arr.OrderBy (x => x, NaturalSort baru ()). ToArray ();

Alasan saya membutuhkannya adalah untuk mengajukannya ke direktori yang nama filenya dimulai dengan angka:

public static FileInfo[] GetFiles(string path)
{
  return new DirectoryInfo(path).GetFiles()
                                .OrderBy(x => x.Name, new NaturalSort())
                                .ToArray();
}
Neil M
sumber
0
Try this out..  



  string[] things = new string[] { "paul", "bob", "lauren", "007", "90", "-10" };

        List<int> num = new List<int>();
        List<string> str = new List<string>();
        for (int i = 0; i < things.Count(); i++)
        {

            int result;
            if (int.TryParse(things[i], out result))
            {
                num.Add(result);
            }
            else
            {
                str.Add(things[i]);
            }


        }

Sekarang Sortir daftar dan gabungkan kembali ...

        var strsort = from s in str
                      orderby s.Length
                      select s;

        var numsort = from n in num
                     orderby n
                     select n;

        for (int i = 0; i < things.Count(); i++)
        {

         if(i < numsort.Count())
             things[i] = numsort.ElementAt(i).ToString();
             else
             things[i] = strsort.ElementAt(i - numsort.Count());               
               }

Saya hanya mencoba memberikan kontribusi dalam pertanyaan menarik ini ...

Syeda
sumber
0

Solusi pilihan saya (jika semua string hanya numerik):

// Order by numerical order: (Assertion: all things are numeric strings only) 
foreach (var thing in things.OrderBy(int.Parse))
{
    Console.Writeline(thing);
}
Bug Raptor
sumber
0
public class Test
{
    public void TestMethod()
    {
        List<string> buyersList = new List<string>() { "5", "10", "1", "str", "3", "string" };
        List<string> soretedBuyersList = null;

        soretedBuyersList = new List<string>(SortedList(buyersList));
    }

    public List<string> SortedList(List<string> unsoredList)
    {
        return unsoredList.OrderBy(o => o, new SortNumericComparer()).ToList();
    }
}

   public class SortNumericComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        int xInt = 0;
        int yInt = 0;
        int result = -1;

        if (!int.TryParse(x, out xInt))
        {
            result = 1;
        }

        if(int.TryParse(y, out yInt))
        {
            if(result == -1)
            {
                result = xInt - yInt;
            }
        }
        else if(result == 1)
        {
             result = string.Compare(x, y, true);
        }

        return result;
    }
}
kumar
sumber
Bisakah Anda menjelaskan kode Anda? Jawaban hanya kode dapat dihapus.
Wai Ha Lee
Postingan Jeff Paulsen membantu saya menerapkan IComparer <string> untuk memperbaiki masalah soring saya. .
kumar
0

Memperluas jawaban Jeff Paulsen. Saya ingin memastikan tidak masalah berapa banyak jumlah atau kelompok karakter dalam string:

public class SemiNumericComparer : IComparer<string>
{
    public int Compare(string s1, string s2)
    {
        if (int.TryParse(s1, out var i1) && int.TryParse(s2, out var i2))
        {
            if (i1 > i2)
            {
                return 1;
            }

            if (i1 < i2)
            {
                return -1;
            }

            if (i1 == i2)
            {
                return 0;
            }
        }

        var text1 = SplitCharsAndNums(s1);
        var text2 = SplitCharsAndNums(s2);

        if (text1.Length > 1 && text2.Length > 1)
        {

            for (var i = 0; i < Math.Max(text1.Length, text2.Length); i++)
            {

                if (text1[i] != null && text2[i] != null)
                {
                    var pos = Compare(text1[i], text2[i]);
                    if (pos != 0)
                    {
                        return pos;
                    }
                }
                else
                {
                    //text1[i] is null there for the string is shorter and comes before a longer string.
                    if (text1[i] == null)
                    {
                        return -1;
                    }
                    if (text2[i] == null)
                    {
                        return 1;
                    }
                }
            }
        }

        return string.Compare(s1, s2, true);
    }

    private string[] SplitCharsAndNums(string text)
    {
        var sb = new StringBuilder();
        for (var i = 0; i < text.Length - 1; i++)
        {
            if ((!char.IsDigit(text[i]) && char.IsDigit(text[i + 1])) ||
                (char.IsDigit(text[i]) && !char.IsDigit(text[i + 1])))
            {
                sb.Append(text[i]);
                sb.Append(" ");
            }
            else
            {
                sb.Append(text[i]);
            }
        }

        sb.Append(text[text.Length - 1]);

        return sb.ToString().Split(' ');
    }
}

Saya juga mengambil SplitCharsAndNums dari SO Page setelah mengubahnya untuk menangani nama file.

Rubah
sumber
-1

Meskipun ini pertanyaan lama, saya ingin memberikan solusi:

string[] things= new string[] { "105", "101", "102", "103", "90" };

foreach (var thing in things.OrderBy(x => Int32.Parse(x) )
{
    Console.WriteLine(thing);
}

Woha cukup sederhana bukan? : D

Oscar Ortiz
sumber
-1
namespace X
{
    public class Utils
    {
        public class StrCmpLogicalComparer : IComparer<Projects.Sample>
        {
            [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
            private static extern int StrCmpLogicalW(string x, string y);


            public int Compare(Projects.Sample x, Projects.Sample y)
            {
                string[] ls1 = x.sample_name.Split("_");
                string[] ls2 = y.sample_name.Split("_");
                string s1 = ls1[0];
                string s2 = ls2[0];
                return StrCmpLogicalW(s1, s2);
            }
        }

    }
}
hamid ramezanali
sumber