当前位置: 首页 > 知识库问答 >
问题:

PowerShell从CSV文件中的所有列中构建所有可能组合的数组

周志文
2023-03-14

我如何从"CSV示例"创建一个像"最终结果"这样的数组?

背景
我正在构建一个用于测试的实验室文件系统,我想创建一个看起来有点像真实文件系统的文件夹结构。我有几个包含文件夹信息的CSV文件。

CSV Example:

Department       Level1                  Level2                Level3
Human Resources  Personnel               Templates             APAC
                 Job Applications        Customer Relations    EMEA
                 Salaries and Expenses   Directors             NA
                 Vacation Tracking       Human Resources       SA
                 Disputes                Legal Services
                                         Marketing
                                         Production
                                         Finance
                                         IT Services

我想采用上面的每个组合,创建一个包含以下所有文件夹的文件系统

End Result:

Human Resources\Personnel\Templates\APAC
Human Resources\Personnel\Templates\EMEA
...
Human Resources\Disputes\IT Services\NA
Human Resources\Disputes\IT Services\SA

一旦我有了上面所有完整路径的数组,就像做一样简单:

foreach($folder in $MyFolderArray){
    New-Item "\\Server\Share$\$folder" -ItemType Directory -Force
}

问题
我希望能够为任何CSV文件做到这一点,不管我有多少列,头名称是什么,或者每列有多少值。目前,我硬编码4 Foreach循环,但该解决方案要求所有CSV文件具有相同数量的列和标题名称。我正在寻找的东西,可以采取任何列计数和长度的任何CSV文件。

从任何CSV获取所有标题的操作如下:

$CSVContent = Import-CSV "C:\PathToMyCSVFile"
$CSVHeaders = $CSVContent[0].PSObject.Properties.Name

这可以用于将$CSVContent拆分为每列一个数组,其中包括:

for($i=0;$i -lt $CSVHeaders.Count;$i++){
    New-Variable -Name "Header$i" -Value $($CSVContent.$($CSVHeaders[$i]) | Where-Object{$_ -ne ""})
}

这将创建从$Header0到$Header的数组,其中#是CSV列数减去1,每个数组具有该列中的所有值。从这些数组开始创建包含所有完整路径的最终数组是我遇到的难题。

问题
如何解决构建foreach(foreach(…循环)的逻辑,该循环枚举所有值组合,而不进行硬编码?我猜这需要递归调用循环本身,但我不确定如何做到这一点。

共有1个答案

山鸿彩
2023-03-14

对于这样的问题,您可以创建一个递归函数。

在计算机科学中,递归是一种解决问题的方法,其中解决方案取决于同一问题的较小实例的解决方案。这些问题通常可以通过迭代来解决,但这需要在编程时识别和索引较小的实例。递归通过使用从自己的代码中调用自己的函数来解决此类递归问题。这种方法可以应用于许多类型的问题,递归是计算机科学的核心思想之一。

# $Data = Import-Csv .\Data.csv
# https://www.powershellgallery.com/packages/ConvertFrom-SourceTable
$Data = ConvertFrom-SourceTable '
Department       Level1                  Level2                Level3
Human Resources  Personnel               Templates             APAC
                 Job Applications        Customer Relations    EMEA
                 Salaries and Expenses   Directors             NA
                 Vacation Tracking       Human Resources       SA
                 Disputes                Legal Services
                                         Marketing
                                         Production
                                         Finance
                                         IT Services'
function Add-Leaves($Path, $i = 0) {
    $Names = $Data[0].PSObject.Properties.Name
    if ($i -lt $Names.count) {
        Foreach ($Leaf in $Data.($Names[$i])) {
            if ($Leaf) { Add-Leaves "$Path\$Leaf" ($i + 1) }
        }
    } else { $Path }
}

Add-Leaves '\\Server\Share$'
\\Server\Share$\Human Resources\Personnel\Templates\APAC
\\Server\Share$\Human Resources\Personnel\Templates\EMEA
\\Server\Share$\Human Resources\Personnel\Templates\NA
\\Server\Share$\Human Resources\Personnel\Templates\SA
\\Server\Share$\Human Resources\Personnel\Customer Relations\APAC
\\Server\Share$\Human Resources\Personnel\Customer Relations\EMEA
...
  • Ad-Leaves($Path,$i=0)
    也从内部调用的递归函数。在哪里:
    • $Path是当前路径,其中叶子将被添加到
    • $i它的列索引,默认:$i=0(第一列)
    • 如果($Leaf){排除列中的空字段,例如第一列部门只有一个项目(人力资源),则应排除其余项目
    • addleaves“$Path\$Leaf”($i1)是实际的递归调用,执行相同的操作:
      • 带有一个$Path,该路径现在包括当前列中的每个$Leaf
      • 在下一列($i1=递归深度)

      如果您真的想要创建文件夹,您可能需要在步骤4.5.之间执行此操作,并实现以下内容:

 类似资料:
  • 假设我有一个数据集: 我使用: 屈服: 我想使用这三行创建不同的组合,为每个组合形成一个数据集。 组合的示例如下: 另一个是: 第三种可能的组合如下: 最后: PS:在前面的示例中,每个组合(一个数据集)至少有两行, 如何在JAVA中实现这一点?非常感谢。

  • 问题内容: 我有一个字符数组c [] [],每个索引都有不同的映射。例如: 我需要以字符串形式返回此数组的所有可能字符组合。也就是说,对于上述字符数组,我应该返回:“ ag”,“ ah”,“ ai”,“ bg”,“ bh”,“ bi”,“ cg”,“ ch”,“ ci”等对于上面只有两件事的字符数组,这样做很容易,但是如果有更多的数组,那么我不知道该怎么办…这就是我要大家提供的帮助!:) 问题答案

  • 我有一个数字数组,现在我必须通过生成给定数组的所有可能子数组并应用一些条件来找到元素之和。 条件是,对于每个子阵列,获取最小值,并找到其中的元素总数,然后将两者相乘(最小值*总数)。最后,将所有子阵列的所有这些相乘值相加。 以下是问题陈述: 使用下面的公式找到所有可能的子数组的总和: 和(左,右)=(最小的arr[i]) * (∑ arr[i]),其中i的范围从左到右。 例子: 子数组是:[sta

  • 问题内容: 在Python中,我有一个n个列表的列表,每个列表具有可变数量的元素。如何创建包含所有可能排列的单个列表: 例如 我想要 注意,我事先不知道n。我以为itertools.product是正确的方法,但它需要我提前知道参数的数量 问题答案: 您不需要事先知道使用

  • 问题内容: 当我尝试做这样的事情时,我意识到我真的需要上大学! 无论如何,我都有一个字符串数组(275),我需要遍历它们并用Java创建所有可能对的字符串。 我一直在学习递归,但是我找不到答案。 问题答案: 如果对和不同,请执行以下操作: 如果没有,请执行以下操作: 请注意,我假设数组包含唯一的字符串!