Powershell Как сгенерировать несколько комбинаций

Я пытаюсь создать функцию, которая сравнивает, соответствует ли начало входной строки одной из возможностей, сгенерированных из комбинаций в нескольких System.Arrays. Результатом этой функции будет возвращенный объект с входными данными GroupName, которые мы получили, и если это действительное имя или нет, $true/$false.

Массив1:

Country
-------
BEL
NLD

Массив2:

Color
----
Green
Red

Массив3:

Type            Object
----            ------
Fruit           Banana
Veggetables     Aubergine
Fruit           Appel
Veggetables     Carrot
Fruit           Peer

Созданный в функции список для проверки достоверности:

BEL Green-Fruit-Banana
BEL Green-Fruit-Appel
BEL Green-Fruit-Peer
BEL Green-Vegetables-Aubergine
BEL Green-Vegetables-Carrot
NLD Green-Fruit-Banana
NLD Green-Fruit-Appel
NLD Green-Fruit-Peer
NLD Green-Vegetables-Aubergine
NLD Green-Vegetables-Carrot
BEL Red-Fruit-Banana
BEL Red-Fruit-Appel
BEL Red-Fruit-Peer
BEL Red-Vegetables-Aubergine
BEL Red-Vegetables-Carrot
NLD Red-Fruit-Banana
NLD Red-Fruit-Appel
NLD Red-Fruit-Peer
NLD Red-Vegetables-Aubergine
NLD Red-Vegetables-Carrot

Код, который у меня уже есть, предназначен для создания объекта. Но я не знаю, как лучше всего создать этот список в функции и заполнить значение Valid.

Function Compare-Names {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
        [string[]]$GroupName
    )
    PROCESS {
        # Generate all options
        <# Fill Valid $true or false here #>

        foreach ($Group in $GroupName) {
            $obj = New-Object -TypeName psobject -Property ([ordered] @{
                'GroupName' = $Group;
                'Valid' = $Valid;
            })
        Write-Output $obj
        }
    }
}

person DarkLite1    schedule 08.08.2014    source источник


Ответы (2)


Итак, я понимаю, что вы уже приняли ответ, но я решил предложить альтернативное решение. Используя сопоставление RegEx с форматом имени группы «Цвет страны-тип-объект» и оператор -Contains, вам даже не нужно генерировать весь список возможных имен.

Function Compare-Names {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
        [string[]]$GroupName
    )
    BEGIN {
        $Array1 = "BEL","NLD"|%{[pscustomobject]@{Country=$_}}
        $Array2 = "Green","Red"|%{[pscustomobject]@{Color=$_}}
        $Array3 = ("Fruit","Banana"),("Vegetables","Aubergine"),("Fruit","Appel"),("Vegetables","Carrot"),("Fruit","Peer")|%{[pscustomobject]@{Type=$_[0];Object=$_[1]}}
        [RegEx]$RegEx = "(.+?) (.+?)-(.+?)-(.+?)$"
    }
    PROCESS {
        ForEach($Group in @($GroupName)){
        $NameSplit = $regex.Match($Group) | Select -ExpandProperty Groups
            [PSCustomObject][ordered] @{
                'GroupName' = $Group
                'Valid' = If($Array1.Country -contains $NameSplit[1] -and $Array2.Color -contains $NameSplit[2] -and $Array3.Type -contains $NameSplit[3] -and $Array3.Object -contains $NameSplit[4]){$true}else{$false}
            }
        }
    }
}

Это выведет все, что передано в него со свойствами GroupName и Valid, поэтому, если вы хотите обрабатывать только те вещи, которые действительны, сделайте что-то вроде:

"BEL Green-Fruit-Banana",
"BEL Green-Fruit-Appel",
"BEL Green-Fruit-Peer",
"BEL Green-Vegetables-Aubergine",
"BEL Green-Vegetables-Carrot",
"NLD Green-Fruit-Banana",
"BEL Green-Fruit-Grape" | Compare-Names | Where{$_.Valid}

Это просто выведет допустимые имена:

GroupName                      Valid
---------                      -----
BEL Green-Fruit-Banana          True
BEL Green-Fruit-Appel           True
BEL Green-Fruit-Peer            True
BEL Green-Vegetables-Aubergine  True
BEL Green-Vegetables-Carrot     True
NLD Green-Fruit-Banana          True

Таким образом, вы можете запустить отчет постфактум с помощью Where{!$_.Valid} и узнать, какие из них не удались, и сформировать список отклоненных.

GroupName             Valid
---------             -----
BEL Green-Fruit-Grape False
person TheMadTechnician    schedule 08.08.2014
comment
Это выглядит более эффективно, чем то, что у меня было раньше. Хотя мой ввод будет что-то вроде "BEL Green-Fruit-Banana Njam njam". Поэтому мне нужно только убедиться, что начало строки правильное. Я попробую это как можно скорее. Спасибо за вашу помощь, очень признателен. - person DarkLite1; 09.08.2014
comment
Регулярное выражение для проверки только начала строки — [RegEx]$RegEx = "(.+?) (.+?)-(.+?)-(.+?)( .+?)?$". Что этот код делает неправильно, так это говорит Valid=$True для недопустимой комбинации, такой как, например, BEL Green-Fruit-Carrot. В этом случае он должен сказать Valid=$False, так как он не соответствует. - person DarkLite1; 11.08.2014
comment
Я объединил Objectи Type в одно значение для PSCustomObject, что решило проблему отсутствия связи друг с другом. - person DarkLite1; 11.08.2014

person    schedule
comment
Спасибо, Дэвид. Но он не генерирует Aubergine и Carrot. Также значение $Valid не заполняется $true или $false. Кроме того, Objects в вашем примере — это System.Object, а не System.Array, как в моем примере. Но это хорошая база для начала. Спасибо чувак! - person DarkLite1; 08.08.2014
comment
Исправлено: опечатка в $Objects.$key (было $Object.$key) - person David Brabant; 08.08.2014
comment
Потрясающий! У меня все еще есть один вопрос: как я могу это сделать, если я обращаюсь к значениям в массиве следующим образом: $Array3.Type и $Array3.Object? Потому что Type и Object - это заголовки столбцов массивов. - person DarkLite1; 08.08.2014
comment
Замените часть $Objects.Keys | % {.....} на $Array3 | % { "$country $color-$($_.Type)-$($_.Object)" } - person Frode F.; 08.08.2014
comment
Совершенно крутые ребята! Большое спасибо, спасли мой день :) - person DarkLite1; 08.08.2014