choooper2006
choooper2006

Reputation: 63

Powershell get random group by id

I need to group objects that were retrieved at random based on an ID that two objects may share.

Here is my current script:

$allRows = Import-CSV C:\Temp\pk.csv

$chosenHouseholdIDs = ($allRows | Get-Random -Count $allRows.count).id

$chosenOnes = $allRows | Where-Object id -in $chosenHouseholdIDs

$i = 1

foreach ($chosenOne in $chosenOnes)
{
     "$($i),$($chosenOne.name)"
     $i = $i + 1
}

The file pk.csv contains 130 rows. Each row has a name and a householdID. The purpose of the householdID is link twins. So if one twin is randomly pulled then the other twin needs to pulled next, or they need to be grouped together.

Sample input looks like this:

householdID,name
7745,Josiah Moon
7746,Finleigh Hayes
7747,Evelyn Brandon
7749,Braedyn Thompson
7750,William Doughty
7751,Madison Vaughn
7751,Morgan Vaughn
7752,Peyton Benford
7753,Robert Waldrop
7754,Johnathan Ford
7755,Cheyenne Holmes
7756,Reid Ruark

Expected output would be something like this:

rowNumber,householdID,name
1,7750,William Doughty
2,7752,Peyton Benford
3,7753,Robert Waldrop
4,7755,Cheyenne Holmes
5,7747,Evelyn Brandon
6,7745,Josiah Moon
7,7746,Finleigh Hayes
8,7756,Reid Ruark
9,7751,Morgan Vaughn
10,7751,Madison Vaughn
11,7754,Johnathan Ford
12,7749,Braedyn Thompson

Notice that the two names with the householdID of 7751 are listed in a random order but are sequentially together in the list. The householdID does not need to be part of the output. I just included it here for illustration purposes.

Upvotes: 1

Views: 310

Answers (2)

mklement0
mklement0

Reputation: 438133

If it's acceptable to change the order of the items as along as identical household IDs are grouped together, you can do the following (I'm omitting the output-formatting code for brevity):

$chosenOnes | Group-Object householdID | ForEach-Object Group 

This will perform the desired grouping, but will return the items sorted by household ID.

The .Group property of the Microsoft.PowerShell.Commands.GroupInfo instances output by the Group-Object cmdlets contains the members of each group and simply outputting each group's members results in a flat array of the input items, but with grouping.


If it's acceptable to randomize the order again, use:

$chosenOnes | Group-Object householdID | 
  Get-Random -Count $chosenOnes.Count | ForEach-Object Group

More work would be needed if you wanted to preserve the original order and only selectively insert the items with the same household ID after their first occurrence.

Upvotes: 1

Erick Guillen
Erick Guillen

Reputation: 595

Use the Group-Object cmdlet. Like this

$chosenOnes = $allRows | Where-Object id -in $chosenHouseholdIDs | Group-Object -Property householdID

Upvotes: 0

Related Questions