Import participants from a CSV file, and sort them into groups

Hi, i have a small script, that reads player-ID, name, clubname and player rank from a CSV file:

$csvFilePath = ".\participants.csv"
$names = Import-Csv -Path $csvFilePath

$names is now filled with information from CSV file, then I want these names into groups, with maximun 4 participants, and minimum 3 participants:

$maxNamesPerGroup = 4
$minNamesPerGroup = 3

And from my CSV list, i want participants to random go to different group, so i uses:

$names = $names | Get-Random -Count $names.Count

When i now execute $names, i see that the list is shuffled.

So, now i want to start from the top of the list, and create groups:

$groups = @()
$currentGroup = @()

But from here, I need new eyes to have a look.
this is so far rest of my script to sort participants into different groups based on the random list i created earlier:

foreach ($name in $names) {
    $currentGroup += $name
    if ($currentGroup.Count -ge $maxNamesPerGroup) {
        $groups += $currentGroup
        $currentGroup = @()
    }
}

# Add any remaining names to the last group
if ($currentGroup.Count -ge $minNamesPerGroup) {
    $groups += $currentGroup
}

# Print the names in the groups
for ($i = 0; $i -lt $groups.Count; $i++) {
    Write-Host "Group $i :"
    $groups[$i]
}

But somehow, this will create one participant per Group, and if i have 12 participants in my CS V list, this script will create 12 groups…

One more thing, i also want the player with highest rank in a group to be player # 1 in that group… But i can figure that out later if someone can help me a bit on my way with getting these participants into groups.

Set of data in CSV file:

Player-ID,Name,Club,Ranking
0001,Player One,Club One,14
0002,Player Two,Club Two,17
0003,Player Three,Club Three,09
0004,Player Four,Club Four,12
0005,Player Five,Club Five,18
0006,Player Six,Club Six,26
0007,Player Seven,Club Seven,24
0008,Player Eight,Club Eight,17
0009,Player Nine,Club Nine,12
0010,Player Ten,Club Ten,19
0011,Player Eleven,Club Eleven,22
0012,Player Twelve,Club Twelve,28

Thanks

Stian,
Welcome to the forum. :wave:t3:

Before we proceed could you please go back, edit your question once agaion and fix the formatting of your code?

When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.

Thanks in advance

How to format code in PowerShell.org 1 <---- Click :point_up_2:t4: :wink:

( !! Sometimes the preformatted text button hides behind the settings gear symbol. :wink: )

Edit:
And you may share a set of sample data (formatted as code as well please) for us to play around with. This way we don’t have to create them by ourselfs

Sorry, i have changed a bit in my post…

Looks much better now. :+1:t3:

Since I am quite lazy and not the smartest man on earth I usually search for solutions others may already have shared and fit to my requirements.

In this case I’d probably use one of the many solutions you can find on StackOverflow on “Cutting An Array Into Slices”.

I picked this:

Now let’s digg in. First we need input data …

$NameList = @'
Player-ID,Name,Club,Ranking
0001,Player One,Club One,14
0002,Player Two,Club Two,17
0003,Player Three,Club Three,9
0004,Player Four,Club Four,12
0005,Player Five,Club Five,18
0006,Player Six,Club Six,26
0007,Player Seven,Club Seven,24
0008,Player Eight,Club Eight,17
0009,Player Nine,Club Nine,12
0010,Player Ten,Club Ten,19
0011,Player Eleven,Club Eleven,22
0012,Player Twelve,Club Twelve,28
'@ | 
ConvertFrom-Csv

Now you wanted to have the elements randomly grouped. So lets randomize the list first …

$RandomNameList = 
    Get-Random -InputObject $NameList -Count $NameList.Count

Now lets cut the randomized list into slices. Since you want to have a maximum of 4 elements per slice we can simply divide the amount of elements by 4. But since we need an integer we have to make sure to always get a whole number as result
(The original author of the function named its parameter this way. So I use the term “chunks” in this case equivalent to “elements” in the array or in one slice)

$NumberOfChunks = 
    [Int][Math]::Ceiling($RandomNameList.count/4)

Now let’s cut the whole list:

$Result = 
    Split-ArrayInChunks_UsingArrayList -inArray $RandomNameList -numberOfChunks $NumberOfChunks

That’s actually it. You have now an array of arrays saved to the variable $Result.

Ah … right …

That’s acvtually an easy one … since the rank is a integer you can simply sort by this porperty. Let’s pick the first slice (index 0):

$Result[0] |
    Sort-Object -Property Ranking -Descending

Easy huh? :blush: :stuck_out_tongue_winking_eye: :smiley: :man_shrugging:t3: :love_you_gesture:t3:

Thanks, but if I now want to output these results, i created this for loop

for ($i = 0; $i -lt $Result.Count; $i++) {
    Write-Host "Group $i :"
    $Result[$i] | Sort-Object -Property Ranking -Descending
}

What i get then is this result:
image

But what I want, and thought my For loop would give me is groups like:
image

If I run selection $i = 0; in the For Loop, and run selection:

    Write-Host "Group $i :"
    $Result[$i] | Sort-Object -Property Ranking -Descending

the output looks nice, and then again run selection $i++ and run the selection aboe over again, a new group is defined… but i thought that the For loop would do that for me

I’m not sure what you’re actually trying to do … :man_shrugging:t3:

If it’s about a nice console output try this:

$Result.GetEnumerator().Name | 
    Sort-Object |
        ForEach-Object {
            'Group # {0}' -f $_
            $Result[$_] | 
            Sort-Object -Property Ranking -Descending |
            Format-Table 
        }

… looks like this:

image

1 Like

This is a very common issue. *-Host commands at parse time go straight to the console where other output happens as executed. You can force the issue by adding Out-Host to the non host commands

for ($i = 0; $i -lt $Result.Count; $i++) {
    Write-Host "Group $i :"
    $Result[$i] | Sort-Object -Property Ranking -Descending | Out-Host
}
1 Like