打印可枚举内容的有效方法 [英] Efficient method to print the content of an Ienumerable
问题描述
我有这个结果"变量,它是一个 IEnumerable
类型:
Dim result = GetCombinations(TextBox1.Text, StringLength)
要获取/写入变量的内容,我需要使用 For 迭代其中的所有项目,然后将每个项目转换为数组,如下所示:
For Each item In resultRichTextBox1.Text += vbNewLine &item.ToArrayApplication.DoEvents()下一个
...所以我的答案是如果我可以改进我的代码,例如加入 IEnumerable 内容来做这样的事情:
RichTextBox1.Text = String.Join(vbNewLine, result) ' 这不起作用.
我的意思是,一次性"的事情.
如果没有,还有比 For 更好(更快)的替代方案吗?
<块引用>更新
这是完整的代码:
私有共享函数 GetCombinations(Of T)(list As IEnumerable(Of T), length As Integer) As IEnumerable(Of IEnumerable(Of T))如果长度 = 1 那么返回列表.[Select](Function(x) New T() {x})别的返回 GetCombinations(list, length - 1).SelectMany(Function(x) list, Function(t1, t2) t1.Concat(New T() {t2}))万一结束函数Private Sub Button1_Click(sender As Object, e As EventArgs) 处理Button1.ClickRichTextBox1.Clear()Dim 结果 = GetCombinations("abc", 5)' Dim result2 As IEnumerable(Of String) = result.Select(Function(item) New String(item))' RichTextBox1.Text = String.Join(vbNewLine, result)For Each item In resultRichTextBox1.Text &= vbNewLine &item.ToArray' Application.DoEvents()下一个结束子
<块引用>
更新 2
Private Sub Button1_Click(sender As Object, e As EventArgs) 处理Button1.Click' 方法结果Dim 结果为 IEnumerable = Permute_Characters("abc", 2)' 将字符串组合成行' 不工作RichTextBox1.Text = String.Join(Environment.NewLine, result.ToString.ToArray)结束子
如果你想要速度和减少内存占用,那么减少递归和对 LINQ 的调用(隐藏内部循环).
既然我明白你想要什么,试试这个代码
公共函数 GetCombinations(ByVal 字母 As String, ByVal word_length As Integer) As String()' abc,2 ->aa、ab、ac、ba、bb、bc、ca、cb、cc' abc,3 ->aaa, aab, aac, aba, abb, abc, .., caa, cab, cac昏暗列表 = 字母.ToCharArray()Dim N_letters = list.LengthDim N_combinations = CLng(Math.Pow(N_letters, word_length))将结果调暗为新列表(字符串)(N_combinations)' indeces 保存每个组合使用的字母' 0 = a, 1 = b, 2 = c, ...' 它以 (0,0,0..) 开头,对应于aaa.."Dim indeces As Integer() = New Integer(word_length-1) {}'默认为0将 k 调暗为整数做' 将 indeces 转换为组合,例如:(1,0,2) =>(b,a,c) =>背"result.Add(New String(indeces.Select(Function(x) list(x)).ToArray()))'通过增加第一个字母找到下一个组合,'如果它溢出,将其重置为'a'并尝试单词中的下一个字母k = 0做indeces(k) += 1如果 indeces(k) = N_letters 那么指数(k)= 0k = k + 1别的退出做万一循环而 k <字长循环而 k <字长返回结果.ToArray()结束函数子主()Dim 结果 = GetCombinations("abc", 5)Debug.WriteLine(String.Join(ControlChars.CrLf, result))结束子
结果
aaaaa呜呜呜卡阿啊啊啊呜呜呜cbaaa阿卡阿支链氨基酸ccaa阿巴巴巴...商会美国广播公司英国广播公司公证处ACCCC密件抄送cccc
I have this "result" var which is a IEnumerable
type:
Dim result = GetCombinations(TextBox1.Text, StringLength)
To get/write the content of the variable I need to iterate all the items inside using a For and then convert each item to an array, like this:
For Each item In result
RichTextBox1.Text += vbNewLine & item.ToArray
Application.DoEvents()
Next
...So my answer is If I can improve my code for example to join the IEnumerable content to do something like this else:
RichTextBox1.Text = String.Join(vbNewLine, result) ' This does not work.
I mean, a "in one go" thing.
If not, any alternative better (faster) than the For?
UPDATE
This is the full code:
Private Shared Function GetCombinations(Of T)(list As IEnumerable(Of T), length As Integer) As IEnumerable(Of IEnumerable(Of T))
If length = 1 Then
Return list.[Select](Function(x) New T() {x})
Else
Return GetCombinations(list, length - 1).SelectMany(Function(x) list, Function(t1, t2) t1.Concat(New T() {t2}))
End If
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
RichTextBox1.Clear()
Dim result = GetCombinations("abc", 5)
' Dim result2 As IEnumerable(Of String) = result.Select(Function(item) New String(item))
' RichTextBox1.Text = String.Join(vbNewLine, result)
For Each item In result
RichTextBox1.Text &= vbNewLine & item.ToArray
' Application.DoEvents()
Next
End Sub
UPDATE 2
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Method result
Dim result As IEnumerable = Permute_Characters("abc", 2)
' Combine strings into lines
' Dont work
RichTextBox1.Text = String.Join(Environment.NewLine, result.ToString.ToArray)
End Sub
If you want speed and reduced memory footprint, then reduce the recursions and calls to LINQ (which hide internal loops).
Now that I understand what you want, try this code
Public Function GetCombinations(ByVal letters As String, ByVal word_length As Integer) As String()
' abc,2 -> aa, ab, ac, ba, bb, bc, ca, cb, cc
' abc,3 -> aaa, aab, aac, aba, abb, abc, .. , caa, cab, cac
Dim list = letters.ToCharArray()
Dim N_letters = list.Length
Dim N_combinations = CLng(Math.Pow(N_letters, word_length))
Dim result As New List(Of String)(N_combinations)
' indeces holds which letter to use for each combination
' 0 = a, 1 = b, 2 = c, ...
' it starts with (0,0,0..) which corresponds to "aaa.."
Dim indeces As Integer() = New Integer(word_length-1) {}
'Default to 0's
Dim k As Integer
Do
' convert indeces into combination, example: (1,0,2) => (b,a,c) => "bac"
result.Add(New String(indeces.Select(Function(x) list(x)).ToArray()))
'Find next combination by incrementing the first letter,
'and if it spills-over, reset it to 'a' and try the next letter in the word
k = 0
Do
indeces(k) += 1
If indeces(k) = N_letters Then
indeces(k) = 0
k = k + 1
Else
Exit Do
End If
Loop While k < word_length
Loop While k < word_length
Return result.ToArray()
End Function
Sub Main()
Dim result = GetCombinations("abc", 5)
Debug.WriteLine(String.Join(ControlChars.CrLf, result))
End Sub
with results
aaaaa
baaaa
caaaa
abaaa
bbaaa
cbaaa
acaaa
bcaaa
ccaaa
aabaa
babaa
...
caccc
abccc
bbccc
cbccc
acccc
bcccc
ccccc
这篇关于打印可枚举内容的有效方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!