迭代多对多数据集

时间:2017-12-01 03:45:06

标签: powershell powershell-v5.0

我几乎就在那里,但不能完全了解我的四个场景。以下四个哈希表表示我需要放入对象的数据。在数据库术语中,节点和角色之间的关系是多对多的。

该代码适用于$testDataB$testDataC,其中每个节点有一个角色,但是,RoleInstance属性不会像{I}期望的那样增加$testDataA属性1}}和$testDataD,每个节点有多个角色。

代码

我用来处理数据方案的代码如下(相应地更改$testDataX):

$nodes = $testDataA.node
$nC = 0
$rC = 0
$oData =@()

foreach($node in $nodes)
{
    $rC++
    for($i = 0; $i -lt $node.nodeQty; $i++)
    {
        $nC++
        foreach($role in $node.roles)
        {
            $oData += [pscustomobject]@{
                NodeInstance = "Node$nC" 
                RoleInstance = "Role$rC"
                Roles = $role | select -ExpandProperty values
            }
        }
    }
}
$oData

以下显示了四种数据方案,其中包含预期输出和从上述代码中获得的实际输出。

1x节点,3x角色:

$testDataA = @(
    @{
        node = @{
            nodeQty = 1
            roles = @(
                @{role = "db"}
                @{role = "appsvr"}
                @{role = "client"}
            )
        }
    }
)

实际输出:

NodeInstance RoleInstance Roles 
------------ ------------ ----- 
Node1        Role1        db    
Node1        Role1        appsvr
Node1        Role1        client

必需输出:

NodeInstance RoleInstance Roles 
------------ ------------ ----- 
Node1        Role1        db    
Node1        Role2        appsvr
Node1        Role3        client

2x个节点,每个节点有1个角色:

#2x nodes, with 1x role each.
$testDataB = @(
    @{
        node = @{
            nodeQty = 1
            roles = @(
                @{role = "db"}
            )
        }
    }
    @{
        node = @{
            nodeQty = 1
            roles = @(
                @{role = "appsvr"}
            )
        }
    }
)

实际输出:

NodeInstance RoleInstance Roles 
------------ ------------ ----- 
Node1        Role1        db    
Node2        Role2        appsvr

必需输出:实际输出是必需的。

总共4个节点,1个节点,1个角色,3个节点,1个角色。

#total of 4x nodes, 1x node with 1 role and 3x nodes with 1 role.
$testDataC = @(
    @{
        node = @{
            nodeQty = 1
            roles = @(
                @{role = "db"}
            )
        }
    }
    @{
        node = @{
            nodeQty = 3
            roles = @(
                @{role = "appsvr"}
            )
        }
    }
)

实际输出:

NodeInstance RoleInstance Roles 
------------ ------------ ----- 
Node1        Role1        db    
Node2        Role2        appsvr
Node3        Role2        appsvr
Node4        Role2        appsvr

必需输出:实际输出是必需的。

总共3个节点,1个节点,1个角色,2个节点,2个角色。

#Total of 3x nodes, 1x node with 1 role, 2x nodes with 2x roles.
$testDataD = @(
    @{
        node = @{
            nodeQty = 1
            roles = @(
                @{role = "db"}
            )
        }
    }
    @{
        node = @{
            nodeQty = 2
            roles = @(
                @{role = "appsvr"}
                @{role = "client"}
            )
        }
    }
)

实际输出:

NodeInstance RoleInstance Roles 
------------ ------------ ----- 
Node1        Role1        db    
Node2        Role2        appsvr
Node2        Role2        client
Node3        Role2        appsvr
Node3        Role2        client

必需输出:

NodeInstance RoleInstance Roles 
------------ ------------ ----- 
Node1        Role1        db    
Node2        Role2        appsvr
Node2        Role3        client
Node3        Role2        appsvr
Node3        Role3        client

我尝试了$nC$rC的多个位置排列,因为看起来这些变量影响最大。我似乎能够让A和D工作,但B和C不会,反之亦然。

如果有人有任何想法,那么我们可以通过自己的方式,我会非常感激。 TIA。

1 个答案:

答案 0 :(得分:0)

我确定它不是很优雅,而且有更好的方法,但以下是我需要的:

#Iterate over test data
$nodes = $testDataC.node
$nC = 0
$oData =@()
foreach($node in $nodes)
{
    for($i = 0; $i -lt $node.nodeQty; $i++)
    {

        $nC++
        $oData += [pscustomobject]@{
            NodeInstance = "Node$nC" 
            Roles = $node.roles
        }
    }
}

#Pull out unique roles and assign an ID for each role
$UniqueRoles = ($oData.roles | select role -Unique).role
$oUnique = @()
$uRC = 1
foreach($uR in $UniqueRoles)
{

    $oUnique += [pscustomobject]@{
        uRole = $ur#.role
        RoleId = $uRC
    }
    $uRC++
}

#Iterate over test data object, getting RoleId where it matches.
foreach($Node in $oData)
{
    foreach($role in $Node.roles)
    {
        [pscustomobject]@{
            NodeInstance = $node.nodeinstance
            RoleInstance = "Role$(($oUnique | Where-Object{$_.uRole -eq $role.role} | Select -First 1).roleId)"
            RoleName = $role.role
        }
    }
}

我很高兴能有更好的表现。

TIA