[linq] order by liczby jako string

[linq] order by liczby jako string
  • Rejestracja: dni
  • Ostatnio: dni
0

Hej posiadam sobie taką tablicę:

Kopiuj
    string[] s = new string[5]
            {
                "1","aa","bb","10", "5"
            };

i chciałbym ją uporządkować. Proste użycie:

Kopiuj
            var a = s.OrderBy(x => x);

uporządkuje ją w ten sposób:

Kopiuj
1
10
5
aa
bb

a ja bym chciał aby została zachowana kolejność liczb:

Kopiuj
1
5
10
aa
bb

Da się to w jakiś prosty sposób zrobić?

Misiekd
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7923
RE
  • Rejestracja: dni
  • Ostatnio: dni
0

Sposób sortowania, o którym piszesz nazywa się "naturalne". Polecam frazę typu natural sort C#.

  • Rejestracja: dni
  • Ostatnio: dni
0

dzięki!

już napisałem własną klasę:

Kopiuj
  class CompareStrings : IComparer<string>
    {   

        public int Compare(string s1, string s2)
        {
            int a;
            int b;
            if (int.TryParse(s1, out a) && int.TryParse(s2, out b))
            {
                return a - b;
            }
            else if (int.TryParse(s1, out a) && !int.TryParse(s2, out b))
            {
                return -1;
            }
            else if (!int.TryParse(s1, out a) && int.TryParse(s2, out b))
            {
                return 1;
            }
            else
            {
                return string.Compare(s1, s2);
            }
        }
    } 

wywołanie :

Kopiuj
   string[] s = new string[5]
            {
                "1","aa","bb","10", "5"
            };


            var a = s.OrderBy(x => x, new CompareStrings());

działa :)

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
0

niepotrzebnie tyle razy wywołujesz TryParse.

Kopiuj
            int a,b;
            bool parsed_a = int.TryParse(s1, out a);
            bool parsed_b = int.TryParse(s2, out b);
            if (parsed_a && parsed_b)
            {
                return a - b;
            }
            else if (parsed_a && !parsed_b)
            {
                return -1;
            }
            else if (!parsed_a && parsed_b) // *
            {
                return 1;
            }
            else
            {
                return string.Compare(s1, s2);
            }

można jeszcze if-y zagnieździć.

*) w tym miejscu na pewno parsed_a będzie równe false. zgadnij dlaczego.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.