我正在使用程序,请参阅此处:Visual Basic Regular Expression Question。我输入字母,程序从列表中返回所有可能的组合。我想改变这行代码...
Dim result = fruits.Where(Function(fruit) Not fruit.Except(letters).Any())
如果我有这个清单:
Dim fruit as List(Of string) from {"apple","orange","pear","banana"}
我输入“p a p l e r”然后它将返回“apple”和“pear”,但是如果我输入“a p l e r”那么它将返回“pear”。我们的想法是返回所有单词,这些单词可以由输入的字母组成,而不会复制任何单个字母。如何优化这个Linq代码?
答案 0 :(得分:1)
这可能更干净,但有效:
Dim fruits As New List(Of String) From { "apple", "orange", "pear", "banana" }
Dim input As String = "a,p,l,e,r"
dim inputLetters = from letter in input.Replace(",", "") group by letter into Group select group.first, Group.Count
dim result = fruits.where(
function(fruit)
dim fruitcounts = from letter in fruit group by letter into Group select group.first, group.count
dim res = from fc in fruitcounts, inputs in inputletters where fc.first = inputs.first andalso fc.count <= inputs.count select fc.first
return res.count = fruit.count
end function
)
编辑 - 我删除了一些不需要的订单,并简化了分组
再次编辑 - 经过一番思考之后,这里有一个版本,它有更多的行,但是更清晰,更好的因素:
Sub Main
Dim fruits As New List(Of String) From { "apple", "orange", "pear", "banana" }
Dim input As String = "a,p,l,e,r"
dim matchingFruits = from fruit in fruits where CanBeMadeFrom(fruit, input)
End Sub
Function StringToFrequencyTable(input as string) as Dictionary(of Char, Integer)
dim freqTable = from letter in input
group by letter into Group
select letter, Group.Count()
return freqTable.ToDictionary(function(g) g.Letter, function(g) g.Count)
end function
Function CanBeMadeFrom(candidate as string, letters as string) as boolean
dim inputLetters = StringToFrequencyTable(letters.replace(",", ""))
dim IsCharInFrequencyTable = function(x) (from entry in inputLetters where entry.Key = x.Key andalso entry.Value >= x.Value).Any()
return StringToFrequencyTable(candidate).All( IsCharInFrequencyTable )
end function
如果我对此做了其他任何事情,我会将CanBeMadeFrom和StringToFrequencyTable变为扩展方法。