2016-11-10 3 views
0

В настоящее время у меня есть список (из строки), который содержит данные, аналогичные:Создание и сортировки массива/ArrayList/список

"207.5,1" 
"373,2" 
"278.5,3" 
"134,4" 
"277,5" 
"674,7" 
"58.5,9" 

К этому списку, я применяю «list.sort» две команды, то «list.Reverse», который, как сделать именно так, как и ожидалось, мой список затем содержит:

"674,7" 
"58.5,9" 
"373,2" 
"278.5,3" 
"277,5" 
"207.5,1" 
"134,4" 

Как вы можете видеть, для всех намерений и целей, это работало отлично, НО, востроглазая заметит, что запись «58,5,9» неуместна и должна быть в нижней части списка.

Я ценю, что сортирую строки здесь, поэтому я обязан потерпеть неудачу. Что мне нужно, чтобы узнать, как я могу скопировать содержимое строк в строке в другой сортируемый контейнер, который хранит мои номера и «индексы» как целые числа и/или синглы? В идеале, я в конечном итоге с массивом или независимо от данных, как это:

674.0,7 
373.0,2 
278.5,3 
277.0,5 
207.5,1 
134.0,4 
58.5,9 

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

+1

String.Split (',') предоставит вам две части, тогда вам нужно только удвоить. Parsse и int.Parsse для разбора чисел. Создайте их в структуре и отсортируйте структуры, основанные на значении. Или, быть гладким и реализовать IComparable (или независимо от того, какой правильный сортируемый интерфейс используется для структур). – Will

ответ

0

Если вы собираетесь использовать данные более одного раза, имеет смысл иметь класс, который представляет его. Таким образом, вы можете дать детали значимым именам, иметь простой способ создания нового элемента, легко манипулировать данными и иметь собственный способ преобразования его в строку.

Это может выглядеть как нагрузка неудобного кода, но вы должны написать только один раз, и тогда ваша жизнь будет гораздо проще, если вы хотите использовать данные:

Option Infer On 
Option Strict On 

Module Module1 

    Public Class Datum 
     Property Number As Decimal 
     Property Index As Integer 

     Sub New() 
      ' default constructor 
     End Sub 

     Sub New(NumberIndex As String) 
      Dim parts = NumberIndex.Split(","c) 
      ' a simple parameter check 
      If parts.Length <> 2 Then 
       Throw New ArgumentException("No comma found in " & NameOf(NumberIndex)) 
      End If 

      Number = CDec(parts(0)) 
      Index = CInt(parts(1)) 

     End Sub 

     Public Overrides Function ToString() As String 
      Return $"{Number},{Index}" 

     End Function 

    End Class 

    Sub Main() 
     Dim myList As New List(Of String) From {"207.5,1", "373,2", "278.5,3", "134,4", "277,5", "674,7", "58.5,9"} 
     Dim myData = (myList.Select(Function(d) New Datum(d))).ToList() 

     Dim dataDescending = myData.OrderByDescending(Function(d) d.Number).ToList() 

     Console.WriteLine(String.Join(vbCrLf, dataDescending)) 

     Console.ReadLine() 

    End Sub 

End Module 

Выходов:

674,7 
373,2 
278.5,3 
277,5 
207.5,1 
134,4 
58.5,9 
+0

Спасибо Andrew - я буду отдавать предпочтение вашему ответу, потому что это тот самый, который имеет для меня наибольший смысл (как я уже сказал, я довольно новичок в этом), и он отлично работает в моем существующем коде. Спасибо также тем, кто нашел время, чтобы попытаться помочь - это очень ценится! :) –

+0

@MalcolmHutcheon Спасибо за отзыв. Кстати, если вы действительно хотите показать «.0» для чисел, вы можете изменить строку 'Return $ '{Number}, {Index}" 'to' Return $ "{Number: N1}, {Index}" '. –

1

Вы можете использовать LINQ, чтобы делать то, что вы хотите. Если вы просто хотите, чтобы строки, отсортированные в правильном порядке, вы можете использовать:

Dim input = { 
    "207.5,1", 
    "373,2", 
    "278.5,3", 
    "134,4", 
    "277,5", 
    "674,7", 
    "58.5,9" 
} 

Dim sorted = 
    From item In input 
    Let n = CDec(item.Split(","c)(0)) 
    Order By n Descending 
    Select item 

Это просто преобразует первое число в десятичную использовать для сортировки. Если вы хотите объекты с двумя числами добытых, вы можете использовать:

Dim sorted2 = 
    From item In input 
    Let parts = item.Split(","c) 
    Select result = New With { .n = CDec(parts(0)), .idx = CInt(parts(1)) } 
    Order By result.n Descending 

Это дает вам IEnumerable анонимных типов с n и idx свойства - вы можете создать класс и создавать экземпляры, которые вместо этого, если вы не» t хотите анонимные типы (например, вам нужно вернуть его из функции).

1

Простейший способ, по крайней мере, в терминах строк кода, заключается в использовании перегрузки Sort, которая допускает Comparer. Однако, если вы будете часто использовать числовые значения для этих вещей, вы должны рассмотреть класс или структуру данных.

можно скопировать содержимое строк на одну строку в другой контейнер сортируемого

Проблема не контейнер, но данные. Строки цифр не сортируются по числовому значению.

Private Function ThingsCompare(x As String, y As String) As Int32 
    Dim xVal As Double = Convert.ToDouble(x.Split(","c)(0)) 
    Dim yVal As Double = Convert.ToDouble(y.Split(","c)(0)) 

    If xVal < yVal Then Return -1 
    If yVal < xVal Then Return 1 

    ' equal, so compare segment 2 
    Dim xVal2 As Double = Convert.ToDouble(x.Split(","c)(1)) 
    Dim yVal2 As Double = Convert.ToDouble(y.Split(","c)(1)) 

    If xVal2 < yVal2 Then Return -1 
    If yVal2 < xVal2 Then Return 1 

    Return 0 
End Function 

Использование:

things.Sort(AddressOf ThingsCompare) 

Учитывая следующие данные:

{"207.5,1", "373,2", "278.5,3", "9.1,1", 
"9.1,9", "134,4", "277,5", "674,7", "58.5,9"} 

(я добавил "9" элементов, потому что, как символы/цифры они будут отсортированы выше, чем все остальные) , Результаты:

9.1,1
9.1,9
58.5,9
134,4
207.5,1
277,5
278.5,3
373,2
674, 7

1

Использование выражений LINQ и лямбда

Dim input = { 
    "207.5,1", 
    "373,2", 
    "278.5,3", 
    "134,4", 
    "277,5", 
    "674,7", 
    "58.5,9" 
} 

' orderedResult is a IOrderedEnumerable(Of String) 
Dim orderedResult = input. 
    OrderByDescending(Function(item) CDec(item.Split(","c)(0))) 

' dictResult is a Dictionary(Of Integer, Decimal) 
' based on the sorted result 
Dim dictResult = orderedResult.ToDictionary(
    Function(item) CInt(item.Split(","c)(1)), 
    Function(item) CDec(item.Split(","c)(0))) 
Смежные вопросы