2

I am a beginner in Powershell and I am seeking help on completing a task.

I have two lists namely:

$name = "a,b,c"

$number = "1,2,3"

I want to print a value from list1 and list2 together in the below format:

{ name = "a", number = "1" }, { name = "b", number = "2" }, { name = "c", number = "3" }

I have tried the below code but I am not achieving the desired result:

Clear-Host
$list1 = "a,b,c"
$list2 = "1,2,3"

foreach ($i in $list1)
{
  $temp1 = $list1 -split ","

  foreach ($j in $list2)
  {
    $temp2 = $list2 -split ","
  }

  $output = "{ value1 = ""$i"", value2 = ""$j"" }"
  echo $output
}

I get the below output after executing the code:

{ name = "a,b,c", number = "1,2,3" }
zett42
  • 25,437
  • 3
  • 35
  • 72
Ajay
  • 25
  • 5
  • 1
    That format looks suspiciously like a PowerShell hash table, or an attempt at JSON. Are you sure you need that as a string? It matters because if the intent is to create objects (and/or JSON) you need a different approach. – Jeroen Mostert Feb 22 '23 at 17:14
  • `$list1.Split(','), $list2.Split(',') | Join-Array -Columns name, number | ConvertTo-Json` using the function from [this answer](https://stackoverflow.com/questions/73640310/different-length-arrays-to-one-csv/73640422#73640422) – Santiago Squarzon Feb 22 '23 at 17:17
  • 1
    You need to find a way to iterate over both arrays _at once_, which isn't directly supported by PowerShell (unfortunately). As a workaround you may use a plain old `for` counting loop or a `foreach` with an additional counter variable. – zett42 Feb 22 '23 at 17:20
  • Have a look at [this Q&A](https://stackoverflow.com/q/31253263/7571258). Chances are that you may want to use a single _hashtable_ instead of two arrays, as explained in the accepted answer. – zett42 Feb 22 '23 at 17:34

2 Answers2

3

You need to do something to turn the strings that you currently have into actual lists (or arrays). You can use the String.Split() method for this:

$list1 = 'a,b,c'.Split(',')

Then to iterate over each item in both lists simultaneously, you can use a traditional for loop - the loop keeps track of the index variable and you can then access the corresponding items in both lists:

$list1 = "a,b,c".Split(',')
$list2 = "1,2,3".Split(',')

$newList = for ($i = 0; $i -lt [Math]::Max($list1.Length, $list2.Length); $i++){
  "{ value1=""$($list1[$i])"", value2=""$($list2[$i])"" }"
}

Replace [Math]::Max with [Math]::Min if you only want pairs that have a value in both lists.


Another option is to "stitch together" the two lists into a new one using the LINQ Zip() extension method:

$list1 = 'a,b,c'.Split(',')
$list2 = '1,2,3'.Split(',')

$newList = [Linq.Enumerable]::Zip($list1, $list2, [Func[string,string,string]]{
  param($a,$b) 

  return "{ value1=""$a"", value2=""$b"" }"
})

This method will only continue until it exhausts the shortest of the two lists.

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
1

Code

$name = "a,b,c"
$number = "1,2,3"

$name = $name.Split(",")
$number = $number.Split(",")
$length = $name.Length

$result = [string]::Empty
for($i =0; $i -lt $length;$i++)
{
    $result+= "{ name=""$($name[$i])"", number=$($number[$i]) }, "
}

Write-Host $result.Substring(0,$result.Length-2)

Output

{ name="a", number=1 }, { name="b", number=2 }, { name="c", number=3 }
Joma
  • 3,520
  • 1
  • 29
  • 32