我有一个List(MatrixComponent),我正在尝试排序。
Public Class MatrixComponent
Public Property Id As Integer
Public Property Matrix As Integer
Public Property Output As String
Public Property Sorts As String()
End Class
我需要对列表进行排序:
Sorts数组中的元素数量可能因对象而异,但如果数组有3个元素,则它将包含3个字符串值,其中任何一个都可以是空字符串。
示例:
请记住,我的示例数据使用存储为字符串的数字,因为我发现它们更容易查看,但是,数组中的值是字符串,应该按字符串排序。你基本上可以有一个包含以下{“10”,“abc”,“1abc5d”}的数组
Dim m As New List(Of MatrixComponent)
m.Add(New MatrixComponent() With {.Id = 1, .Output = "c:\a.pdf", .Sorts = {"10", "30"}})
m.Add(New MatrixComponent() With {.Id = 2, .Output = "c:\a.pdf", .Sorts = {"10"}})
m.Add(New MatrixComponent() With {.Id = 3, .Output = "c:\a.pdf", .Sorts = {"10", "20"}})
m.Add(New MatrixComponent() With {.Id = 4, .Output = "c:\a.pdf", .Sorts = {}})
m.Add(New MatrixComponent() With {.Id = 5, .Output = "c:\a.pdf", .Sorts = {"9", "1"}})
m.Add(New MatrixComponent() With {.Id = 6, .Output = "c:\a.pdf", .Sorts = {"10"}})
我期待以下顺序:
4, 2, 6, 3, 1, 5
Id Col1 col2 col3
=======================================
4 NULL NULL NULL
2 10 NULL NULL
6 10 NULL NULL
3 10 20 NULL
1 10 30 NULL
5 9 1 NULL
id=4, sort=""
id=2, sort="10"
id=6, sort="10"
id=3, sort="10", "20"
id=1, sort="10", "30"
id=5, sort="9", "1"
我能够通过以下Linq查询获得正确的顺序:
Dim sorted As IOrderedEnumerable(Of MatrixComponent) =
items.OrderBy(Function(u) u.Output) _
.ThenBy(Function(y) If(y.Sorts Is Nothing, "", y.Sorts(0))) _
.ThenBy(Function(y) If(y.Sorts Is Nothing OrElse y.Sorts.Length <= 1, "", y.Sorts(1))) _
.ThenBy(Function(y) If(y.Sorts Is Nothing OrElse y.Sorts.Length <= 2, "", y.Sorts(2)))
答案 0 :(得分:2)
我只是连接Sorts
数组中的字符串,然后按该组合字符串排序。
答案 1 :(得分:1)
有很多我们都不知道。这假定:
Dim sorts As String() = {"10", "35", "20", "50", "40"}
Dim matList As New List(Of MatrixComponent)
matList.Add(New MatrixComponent With {.Id = 1, .Matrix = 1})
matList.Add(New MatrixComponent With {.Id = 99, .Matrix = 9})
matList.Add(New MatrixComponent With {.Id = 78, .Matrix = 7})
matList.Add(New MatrixComponent With {.Id = 4, .Matrix = 6})
matList.Add(New MatrixComponent With {.Id = 43, .Matrix = 3})
matList.Add(New MatrixComponent With {.Id = 123, .Matrix = 12})
' add randomized sort data
For Each m In matList
' sets a random number 0-3 values
m.Sorts = sorts.OrderBy(Function(r) RNG.Next()).Take(RNG.Next(0, 3)).ToArray
Next
' force a "" into one of them:
matList(2).Sorts = {"", "10", "35", "60", "20"}
Dim sortedlist = matList.OrderBy(Function(x) GetSortValue(x.Sorts, 0)).
ThenBy(Function(y) GetSortValue(y.Sorts, 1)).
ThenBy(Function(z) GetSortValue(z.Sorts, 2)).ToList()
然后是帮手:
Private Function GetSortValue(strArry As String(), ndx As Int32) As Int32
Dim intVal As Int32 = Int32.MaxValue
If ndx < strArry.Length Then
If Int32.TryParse(strArry(ndx), intVal) Then
Return intVal
Else
Return Int32.MaxValue
End If
End If
Return intVal
End Function
帮助程序将字符串(如果存在)解析为整数,并在不存在时返回高默认值。从技术上讲,它不完全是一条线linq链。帮助者可以用1-2 x = If()
运算符替换,但我不确定在那里粘贴3次会更清楚。
测试:
For Each m In sortedlist
Console.WriteLine("{0:000} {1}", m.Id, String.Join(", ", m.Sorts))
Next
输出:
078 20, 10, 35, 60, 004 20, 10 099 35, 20 123 40 001 043
(第一个数字是Id)
我喜欢使用字符串数组的concat进行简单排序的想法。这有一些限制:没有单个数字(也许没有9
s)。例如,给出以下数据:
Dim sorts As String()() = {New String() {"10", "90", "20", "35", "40"},
New String() {"10", "9", "2", "35", "40"},
New String() {"1", "90", "9", "35", "40"},
New String() {"19", "90", "20", "35", "40"},
New String() {"20", "9", "20", "35", "40"},
New String() {"2", "90", "20", "35", "40"}
}
结果非常错误:
001 1090203540 099 10923540 078 19093540 004 1990203540 043 209203540 123 290203540
为第78号分配了{"1", "90", "9", "35", "40"}
因此它应该排在第一个元素的顶部。 "19093540"
中从第二组转移的前九个影响整体排序。按数值排序:
078 1,90,9,35,40 123 2,90,20,35,40 099 10,9,2,35,40 001 10,90,20,35,40 004 19,90,20,35,40 043 20,9,20,35,40
123
元素更有趣。 "2"
应该排在第二位。 "290"
不一样,并将其放在最底层。
String.Join
/ Concat可以正常工作,但依赖于数据的性质。如果字符串数组是数字,并且您希望按数值排序,则必须将它们转换为数字。数字和数字排序不同。
答案 2 :(得分:0)
最后,我的解决方案始终如一。问题是这一行:
Dim maxSorts As Integer = sorted.Max(Function(x) If(x.Sorts Is Nothing, 0, x.Sorts.Length))
For i = 0 To maxSorts
我应该早点抓住这个,但是它滑倒了我。获取要迭代的Max数组长度是从1开始的,但是数组元素从0开始。我实际上对列表进行了多次排序,这是重置排序顺序。愚蠢的问题。
答案 3 :(得分:-1)
这对你有用吗?
Dim sorted = _
matrixComponents _
.OrderBy(Function (m) String.Join("|", If(m.Sorts, { }))) _
.ToList()