1

I am trying to iterate over an array $dailyTasks to find 'Blank' i.e. '' values in the EmployeeName column and inject names from another array into those empty values.

Example of what the array looks like before the for loop starts:

| Task  | EmployeeName | EmployeeName2 |
|-------|--------------|---------------|
| Task1 |              |               |
| Task2 | Person Y     |               |
| Task3 |              |               |
| Task4 | Person Z     | Person X      |

This is my for loop code that produces an undesired result. $randomisedUsers is an Object[]

$randomisedUsers | Group-Object { $_ -in ($randomisedUsers | Select-Object -Last 2) } | ForEach-Object {
    if ($_.Name -eq 'True') {
            for ($i = 0; $i -lt $dailyTasks.Count; $i++) {
                if ($dailyTasks[$i].Task -eq 'Task4') {
                    $dailyTasks[$i].EmployeeName = $_.Group.EmployeeName[0]
                    $dailyTasks[$i].EmployeeName2 = $_.Group.EmployeeName[1]
                }
            }
    } else {
            for ($i = 0; $i -lt $dailyTasks.Count; $i++) {
                if ($dailyTasks[$i].EmployeeName -eq '') {
                    if ($_.Count -gt '1') {
                        for ($x = 0; $x -lt $_.Group.EmployeeName.Count; $x++) {
                            $dailyTasks[$i].EmployeeName = $_.Group.EmployeeName[$x]
                        }
                    } else {
                        $dailyTasks[$i].EmployeeName = $_.Group.EmployeeName
                    }
                }
            }
    }
}

Result:

| Task  | EmployeeName | EmployeeName2 |
|-------|--------------|---------------|
| Task1 | Person A     |               |
| Task2 | Person Y     |               |
| Task3 | Person A     |               |
| Task4 | Person Z     | Person X      |

The problem here is that $_.Group.EmployeeName contains two objects but for whatever reason the result table doesnt populate Person B in the array:

$_.Group.EmployeeName

{Person A, Person B}

The desired result in this case is:

| Task  | EmployeeName | EmployeeName2 |
|-------|--------------|---------------|
| Task1 | Person A     |               |
| Task2 | Person Y     |               |
| Task3 | Person B     |               |
| Task4 | Person Z     | Person X      |

Im not completely sure where im going wrong in my for loops and i've been stuck on this for a while...

TIA

3
  • 2
    What is $_? This automatic variable is usually used in a ForEach-Object -Process block however there is not one in your code. Commented Jul 18, 2021 at 23:32
  • @Daniel correct its from a ForEach block. Apologies i didnt think it was necessary to include it Commented Jul 18, 2021 at 23:40
  • 1
    As an aside: You probably meant $_.Count -gt 1 - no reason to use '1', which suggests lexical comparison; however, it is the data type of the LHS that matters: the RHS is coerced to the LHS' data type. Commented Jul 18, 2021 at 23:59

1 Answer 1

2

I would personally use something like this:

$csv = @'
Task,EmployeeName,EmployeeName2 
Task1,,
Task2,Person Y,
Task3,,
Task4,Person Z,Person X      
'@ | ConvertFrom-Csv

$fillEmployees = [System.Collections.ArrayList]@(
    'Person A'
    'Person B'
)

foreach($line in $csv)
{
    if([string]::IsNullOrWhiteSpace($line.EmployeeName))
    {
        $line.EmployeeName = $fillEmployees[0]
        $fillEmployees.RemoveAt(0)
    }
}

The flow is quite simple, if the loop finds a value in EmployeeName that is null or has white spaces it will replace that value with the index 0 of $fillEmployees and then remove that index 0 from the list.

It's hard to tell what you're trying to accomplish with your code, but if you have an array of the type System.Array filled with random names which will be used to fill this empty values on EmployeeName you can convert that Array to an ArrayList which will allow you to use the .RemoveAt(..) method:

PS /> $fillEmployees = 0..10 | ForEach-Object {"Employee {0}" -f [char](Get-Random -Minimum 65 -Maximum 90)}

PS /> $fillEmployees
Employee J
Employee S
Employee D
Employee P
Employee O
Employee E
Employee M
Employee K
Employee R
Employee F
Employee A

PS /> $fillEmployees.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

Attempting to Remove an item from an Array would result in the following:

PS /> $fillEmployees.RemoveAt(0)
Exception calling "RemoveAt" with "1" argument(s): "Collection was of a fixed size."
At line:1 char:1
...
...

However if convert it to an ArrayList (not convert it but copy it):

PS /> $fillEmployees = [System.Collections.ArrayList]$fillEmployees

PS /> $fillEmployees.RemoveAt(0)
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the elegant answer, i will try and implement it on my side now and let you know how it goes.
@ayushlal Show me where the "employees to fill" are coming from and I'll show you how you can implement this solution.
@ayushlal see my edit, hopefully makes sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.