简体   繁体   English

Powershell递归失败? 返回时清除变量

[英]Powershell recursion failing? Variable clears when returned

I'm trying to create a list of "sentences" of 1-8 "words", provided a list of words, where I don't care about uniqueness as I can just filter out duplicates later. 我正在尝试创建1-8个“单词”的“句子”列表,并提供单词列表,在这里我不关心唯一性,因为以后可以过滤出重复项。 I decided that a recursive function would be the best method, particularly in case I wanted to change the maximum length at a later time. 我认为递归函数将是最好的方法,尤其是在以后要更改最大长度的情况下。

When I ran this code, I came back with an empty result. 当我运行这段代码时,我返回了一个空结果。 When I debugged and stepped through it, I found that $sents would contain data right before a return statement, then have no data immediately after returned to the $sents variable in the first else statement. 当我调试并逐步执行它时,我发现$ sents会在return语句之前包含数据,然后在第一个else语句中返回$ sents变量后立即没有数据。

This is the second recursive function I've written for PowerShell and neither worked. 这是我为PowerShell编写的第二个递归函数,但都不起作用。 The first I ended up breaking down and wrote 4 nested foreach statements. 我第一次分解并写了4个嵌套的foreach语句。 This one would be 8 nested statements (I do not wish to do that) just to build a String array of sentences so I can process them. 这将是8个嵌套语句(我不希望这样做),只是为了构建一个句子的String数组,以便我可以处理它们。

Any help would be appreciated. 任何帮助,将不胜感激。 Thank you! 谢谢!

function make-sentences ($ws, $ml, [String[]] $sent = @(), [String[]] $sents = @()) {
    [String[]] $nws = @()
    $sent += $ws[0]

if ($sent.length -ge $ml) {
    $sents += ($sent -join ",")
    return $sents
} elseif ($ws.length -le 1) {
    $sents += ($sent -join ",")
    return $sents
} else {
    for ($i = 1; $i -lt $ws.length; $i++) { $nws += $ws[$i] }
    $sents += make-sentences $nws $ml $sent $sents
}

[String[]] $nws = @()

if ($ws.length -le 1) {
    $sents += ($sent -join ",")
    return $sents
} else {
    $sent = @()
    for ($i = 1; $i -lt $ws.length; $i++) { $nws += $ws[$i] }
    $sents += make-sentences $nws $ml $sent $sents
}
}

$words = ("acfj","acfk","adfk","aefj","aefk","aegi","aehi","afgh")
[String[]] $sentences = make-sentences $words 8

$sentences

Sorry, I don't spent much time reading your code, but a thing you must know is that in PowerShell when you call a function the default behaviour for the parameters is the following (calling by argument): 抱歉,我没有花太多时间阅读代码,但是您必须知道的是,在PowerShell中调用函数时,参数的默认行为如下(通过参数调用):

function Dumy ($param1)
{
  $param1 = 100
  Write-Host "$param1 in function Dumy"
}


$param1 = 10
Write-Host "$param1 in main function before call to Dumy"
Dumy $param1
Write-Host "$param1 in main function after call to Dumy"

It gives: 它给:

10 in main function before call to Dumy
100 in function Dumy
10 in main function after call to Dumy

If you want to modify the value of your parameter, you should use a calling by reference: 如果要修改参数的值,则应使用引用调用:

function Dumy ([ref]$param1)
{
  $param1.value = 100
  Write-Host "$($param1.value) in function Dumy"
}


$param1 = 10
Write-Host "$param1 in main function before call to Dumy"
Dumy ([ref]$param1)
Write-Host "$param1 in main function after call to Dumy"

It gives: 它给:

10 in main function before call to Dumy
100 in function Dumy
100 in main function after call to Dumy

Another solution is to use the variable scope to modify the variable in a function in the calling scope (for me it's like using global variables). 另一种解决方案是使用变量作用域在调用作用域中的函数中修改变量(对我来说,这就像使用全局变量一样)。

I think your $sentences variable is empty, because your function - even if recursive - doesn't have a return statement. 我认为您的$sentences变量为空,因为您的函数-即使是递归的-也没有return语句。 You have a return statement for terminal cases only, but you don't ask for a return statement when calling the function recursively. 您仅具有针对极端情况的return语句,但是在递归调用函数时不要求返回语句。 Then, your function returns something inside the call stack, but your main call is not asked to return anything. 然后,您的函数在调用堆栈返回了一些内容 ,但是没有要求您的主调用返回任何内容。

Here are two example of recursive functions for factorial, the first one looks like your implementation, and does not return anything. 这是两个阶乘递归函数的示例,第一个看起来像您的实现,并且不返回任何内容。 Indeed, the recursive calls are stored in a variable, and then the function doesn't return anything. 实际上,递归调用存储在一个变量中,然后该函数不返回任何内容。 The second example does return something, because in every case, the function is asked to return a value, even through a recursive call : 第二个示例确实返回了一些内容,因为在每种情况下,即使通过递归调用,都要求该函数返回一个值:

function fact-Noresult ([int]$n, [int]$result=1){
  if ($n -eq 0) {
    Write-Host "returning now ! value = $result"
    return $result
  }else {
    $result = $n * (fact-Noresult ($n-1) ($result*$n))        
  }
}

function fact-WithResult ([int]$n, [int]$result=1){
  if ($n -eq 0) {
    return $result
  }else {
    $result=$n*$result
    fact-WithResult ($n-1) $result

  }
}

If you try to call them, you'll see that the first one display the message, and display the good value, but does not return it. 如果尝试调用它们,则会看到第一个显示消息,并显示正确的值,但不会返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM