2016-03-04 3 views
-4

Как отсортировать это на C#. Сначала я хочу сортировать цифры & буквы в алфавитном порядке. Код не идет туда, где игнорируется другая часть кода. В основном заинтересованы в его сортировке.Сортировка чисел, а затем буквы в строковом массиве

interface vehicle 
{ 
    void Mon(); 
} 

class order : vehicle 
{ 
    public void Mon() 
    { 
     string[] arr = new string[] 
     { 
      "B $15", 
      "A $251", 
      "B $5", 
      "B $25", 
      "A $250", 
      "A $45" 
     }; 
    } 
} 
class ABC 
{ 
    public static void Main(string[] args) 
    { 

    } 
} 
} 

поэтому мой ожидаемый результат будет:

A $5 
    A $15 
    A $25 
    B $45 
    B $250 
    B $251 
+0

, пожалуйста, укажите пример вашего ожидаемого результата для ясности. – ibiza

+0

покажите нам, что вы пробовали, дайте нам четкий пример того, что вы хотите, как вы хотите его отсортировать. –

+1

@ Valentin, если вы собираетесь сделать это, вам также придется отбрасывать int и обрезать $ –

ответ

3
var lettersAndNumbers = arr.Select(x => x.Split('$')); 
var orderedLetters = lettersAndNumbers.Select(x => x[0]).OrderBy(x => x); 
var orderedNumbers = lettersAndNumbers.Select(x => int.Parse(x[1])).OrderBy(x => x); 
string[] result = orderedLetters 
    .Zip(orderedNumbers, (letter, number) => letter + "$" + number).ToArray(); 
+0

Это выглядит как лучший ответ, разделяющий на $ - перемещение босса –

+0

хорошее использование 'Zip'! Немного известный оператор LINQ, который мы должны использовать вместо традиционных для циклов. Благодаря! – ibiza

0

Это должно выглядеть примерно так, это при условии, что формат является правильным.

var values = arr.Select(x => x.Split(' ')).ToList(); 

var strList = values.Select(x => x[0]).OrderBy(x => x).ToList(); 

var intList = values.Select(x => Int32.Parse(x[1].SubString(1))) 
                  .OrderBy(x => x).ToList(); 


foreach (var pair in strList.Zip(intList)) 
{ 
    //Do work with pair.Key and pair.Value 
} 
+1

* .Skip() * Вы уверены? – xanatos

+0

@xanatos ваше право Я не должен делать это таким образом, что он преобразуется в массив char –

0

кажется, что вы хотите числа в строках можно сравнить, как числа (например, при сравнении "A $5" и "A $15" мы сравним "A $" части lexicogoraphically, а 5 и 15 как целые числа и, таким образом, "A $5" < "A $15"); в этом случае попробуйте следующее:

using System.Runtime.InteropServices; 

[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] 
private static extern int StrCmpLogicalW(string x, string y); 

... 

Array.Sort(arr, (left, right) => StrCmpLogicalW(
    Path.GetFileNameWithoutExtension(left), 
    Path.GetFileNameWithoutExtension(right))); 
+0

Я пытаюсь выяснить причину, по которой это произошло.Помимо рекомендации Дэвида изменить тип данных (что может не сработать, если это просто пример игры), это идеальное решение, поскольку оно использует существующий код, который был полностью отлажен и протестирован. –

+0

действительно ..? использование 'dllImport' и' interop' для решения этой проблемы ....? – ibiza

+0

Это не будет работать в соответствии с требованиями пользователей, обратите внимание, что он соответствует значениям a с некоторыми номерами b –

0

Это выводит ожидаемый результат:

 string[] arr = new string[] 
    { 
     "B $15", 
     "A $251", 
     "B $5", 
     "B $25", 
     "A $250", 
     "A $45" 
    }; 
     var arrSplited = arr.Select(i => i.Split(' ')); 

     var letters = arrSplited 
      .Select(i => i[0]) 
      .OrderBy(i => i) 
      .ToArray(); 

     var numbers = arrSplited 
      .Select(i => i[1]) 
      .OrderBy(i => Convert.ToInt32(i.Replace("$", "").Trim())) 
      .Select(i => i.ToString()) 
      .ToArray(); 

     var result = new List<string>(); 
     for (int i = 0; i < letters.Length; i++) 
     { 
      result.Add(letters[i]); 
      result.Add(numbers[i]); 
     } 

Ну, не больше, так как вы изменили его в вашем вопросе. Удачи.

0

Что вы имеют это один массив строк. Что вы хотите - это два массива (один из символов или строк и один из цифр данных для достижения интуитивно понятного вида). Что-то вроде этого:

var firstValues = new List<char> { 'B', 'A', 'B', 'B', 'A', 'A' }; 
var secondValues = new List<int> { 15, 251, 5, 25, 250, 45 }; 

Сортировка им каждый:

var sortedFirst = firstValues.OrderBy(v => v).ToList(); 
var sortedSecond = secondValues.OrderBy(v => v).ToList(); 

Затем вы можете объединить их в единую структуру данных для ваших нужд:

var sortedList = sortedFirst.Select((element, index) => 
    new { First = element, Second = sortedSecond[index] }); 

(Обратите внимание, что это предполагает, что оба списка имеют одинаковую длину. Вы можете добавить некоторые условные проверки для подтверждения этого на всякий случай.)

Смежные вопросы