I'm trying to sort a list of objects by a date property, but the dates aren't ordered correctly. I've tried passing them to an array and using Array.Sort
and I've also tried passing them to a list and using List.OrderBy(Function(x) x.requestClose)
, where the property requestClose
is a date, but I get the same result.
For example, say I have the following dates:
11/9/2015,
11/20/2015,
11/10/2015
What I want is the list to be arranged as:
11/9/2015,
11/10/2015,
11/20/2015
but what I'm getting is:
11/10/2015,
11/20/2015,
11/9/2015
The date property is declared as:
Public requestClose As Date
and later used with:
DateTime.TryParse(formAddEquip.dtpCxDate.Value, newEquip.requestClose)
I was able to get it to work by creating a separate sort, specifically for the case when sorting by the date. The issue, as pointed out by people here, is that the keyArray()
was being assigned a String and not a Date. Is there a convenient way to declare this array to avoid having to call what is essentially the same sub-routine that differs only by array variable type?
Public Sub dateSort()
Dim thisEquipList As New classEquipCollection
thisEquipList.Clear()
Dim keyArray() As Date 'THIS IS WHERE IT WAS PREVIOUSLY DECLARED A STRING; string sorting is still needed for other sorting, such as by equip.name
'
ReDim keyArray(0 To project.equipList.Count - 1)
'create an array of the search terms
For i = 1 To project.equipList.Count
keyArray(i - 1) = project.equipList(i - 1).requestClose
Next
Array.Sort(keyArray)
'remove duplicats in the key array
Dim dupeFound As Boolean
Dim newKeyArray() As String
ReDim newKeyArray(0 To 0)
Dim noDupeIndex As Integer
'new key array holds only non-duplicates
For i = 0 To UBound(keyArray)
dupeFound = False
For j = (i + 1) To UBound(keyArray)
If keyArray(j) = keyArray(i) Then
dupeFound = True
End If
Next j
'if a unique key, add it to the non-duplicate array
If dupeFound = False Then
ReDim Preserve newKeyArray(0 To noDupeIndex)
newKeyArray(noDupeIndex) = keyArray(i)
noDupeIndex = noDupeIndex + 1
End If
Next i
'match the equipment item to the search term and
For i = 0 To UBound(newKeyArray)
For Each item In project.equipList
If newKeyArray(i) = item.requestClose Then
thisEquipList.Add(item)
End If
Next
Next
'now that the list is sorted, assign it to project equiplist
project.equipList.Clear()
For i = 0 To thisEquipList.Count - 1
project.equipList.Add(thisEquipList(i))
Next
End Sub
Old now, but showed up today in the unanswered view, and the entire method can be greatly simplified:
Public Sub dateSort()
project.equipList = project.equipList.OrderBy(Function(e) e.requestClose).
GroupBy(Function(e) e.requestClose).
Select(Function(g) g.First()).
ToList()
End Sub
Note this assumes that .Net's Linq operators all use stable sorts and processes that will preserve the original order. I believe this is currently the case, but it hasn't always been so and, while likely to remain unchanged for the foreseeable future, could change again. If stable sorts can not be guaranteed, you may need to add an additional .OrderBy()
within the Select()
to ensure choosing the correct item, and then move the main OrderBy()
to after the Select()
.
使用OrderBy扩展方法时 ,需要确保使用结果集来查看正确的排序。
Dim lstSortedList As List(Of YourObject) = lstOriginal.OrderBy(Function(objTarget) objTarget.requestClose).ToList()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.