我有一个有效的Powershell函数,它使用System.Speech使用Get-Random cmdlet从文本文件中读出随机行。
不幸的是,随机函数cmdlet本身似乎没有做得那么好,因为它重复了相同的行方式太多次。
我的文字文件只包含句子。
function suggestion{
$suggestion=(Get-Random -InputObject (get-content C:\Tools\linesoftext.txt))
Add-Type -AssemblyName System.Speech
$synth = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer
$synth.Speak($suggestion)
}
我不确定我是否可以修改我的内容,或者重新思考我试图随机化输出的方式 - 可能是通过跟踪已播放的内容和循环? (我有点难过。)
答案 0 :(得分:2)
我喜欢Mathias关于在发布时改变线条的建议,但如果你想保留随机选择一条线的主题,但只是不想一遍又一遍地听到相同的线条设置一个阈值,它不会重复并在全局变量中存储那么多项,然后将最后一个语音行添加到它,并在你说出一行时删除第一个项目。类似的东西:
function suggestion{
$lines = get-content C:\Tools\linesoftext.txt
$suggestion= Get-Random -InputObject ($lines | Where{$_ -notin $global:RecentSuggestions})
[array]$global:RecentSuggestions += $suggestion
If($global:RecentSuggestions.count -gt 20){$global:RecentSuggestions = $global:RecentSuggestions | Select -Skip 1}
Add-Type -AssemblyName System.Speech
$synth = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer
$synth.Speak($suggestion)
}
这将跟踪最多20行,并从行列表中排除那些随机选择的行。
答案 1 :(得分:1)
我将它加载到我的$ profile并从Powershell命令提示符调用它。
在这种情况下,您可以使用您的配置文件将行读入内存,然后随机 shuffle 它们,这样相同的行不会重复。要在列表中前进,您可以使用ScriptProperty
,如下所示:
Add-Type -AssemblyName System.Speech -ErrorAction SilentlyContinue
# One synthesizer on per shell should be enough
$__synth = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer
# Read lines of text into memory, shuffle their order
$__lines = Get-Content C:\Tools\linesoftext.txt |Sort-Object {Get-Random}
# Add a script property to the $__lines variable that always returns the next sentence
$ScriptProperty = @{
Name = 'NextSentence'
MemberType = 'ScriptProperty'
Value = {
return $this[++$global:__idx % @($this).Count]
}
}
Add-Member @ScriptProperty -InputObject $__lines
# Speak the next sentence
function Get-Suggestion {
$global:__synth.Speak($global:__lines.NextSentence)
}
# Define alias `suggestion -> Get-Suggestion`
Set-Alias suggestion Get-Suggestion