Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
393 views
in Technique[技术] by (71.8m points)

powershell - How can I return the position a nested array is in, from the value of the first element?

Hopefully that title makes sense!

I have an array, which is made up of 48 sets of 3 numbers. What I now want to do is print these sets of 3 numbers in a pre-defined order, based on the first number in that set of 3. The sub-array is like so:

@($label, $number1, $number2)

There will be 48 sets of these, the label is always unique and is pulled from the title of a CSV file. (The CSV files are fed through various PowerShell scripts to tidy their titles and convert them to XLS, and to run various macros on.) They go through in file order, but I want to print them out in another pre-defined order of my choosing.

So in order to print them in the order of label I would like, I need to be able to test the $label part of the sub-array. If it matches the label I want, print the set of 3 out.

To test my code so far I have constructed a loop that populates my array:

$results = @(1 .. 48)

$label = 148
$var1 = 5
$var2 = 3

for($i = 0; $i -le 47; $i++) {
    $results[$i] = @($label, $var1, $var2)
}

What I need to do now is print these sets of 3 in a particular order, which I will dictate by the label. The next section of code will probably just be a custom function like posArray($label). As I type this out I realise it would be just as useful to print the part of the array with the label in, it doesn't have to necessarily tell me which position it is.

Please feel free to suggest better ways to architect this if possible. It must run in PowerShell though. I thought about maybe a hash, but as it's two vars not just a pair I wasn't sure.

I've tried to go back round the loop and check the first element in each of the nested arrays, but it prints out "System.Object[]" a load of times.

for($i = 0; $i -le 47; $i++) {
    if($results[$i][0] -eq $label) {
        Write-Host "$results[$i]"
    }
}

So I'm not really sure what's happening there.

Ideally if this was the case (the for loop searching and printing the 1 set by $label) I'd put the loop in a function, call the function by FunctionName($label) and I would call the function a bunch of times with the labels in my desired order.

Essay over...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Instead of nested arrays, which could work, I think your would have a much better experience with custom objects. This should work in 2.0

$dasData = 0..47 | ForEach-Object{
    New-Object -TypeName psobject -Property @{
        # Create an object with a nested array.
        Index = $_
        Details = [char]([int]$_ + 65),(Get-Random -Minimum 0 -Maximum 50),(Get-Random -Minimum 0 -Maximum 50)
    }
}

I just made an object array where each object has an index and an array of 3 values. Ignore the actual values. It is just some ANSI printable characters and random numbers. Looking at the first couple of elements of $dasData ...

Details     Index
-------     -----
{A, 15, 6}      0
{B, 28, 31}     1
{C, 41, 23}     2
{D, 0, 7}       3

So now powered with that information we can just use standard PowerShell cmdlets to get the information you are looking for.

$dasData | Where-Object{$_.Details[0] -ceq "F"}

We are looking for the data that matches the element where the first element of details is equal to capital F. That would return the 5th element in the array.

Details     Index
-------     -----
{F, 49, 43}     5

And if you were really just interested in the index then a simple select would get that for you.

$dasData | Where-Object{$_.Details[0] -ceq "F"} | Select-Object -ExpandProperty Index

In your second code set you are not calling the element properly because you are casting it as a string.

Write-Host "$results[$i]" 

Should instead be either of the following.

Write-Host "$($results[$i])" 
Write-Host $results[$i]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...