1

I have this code in Powershell:

for (($i = 0), ($j = 0); $i -lt 10; ($i++))
{
$i
$j
$a2[0+4]

}

How can I make the variable $a2 get +4 every time? Now it happens only once, the variable $a2 contains the text

Above is the code I tried

UPD1:

$a2 contains:

id1
title1
Description1
Rew1
id2
title2
Description2
Rew2
id3
title3
Description3
Rew3
id4
title4
Description4
Rew4
id5
title5
Description5
Rew5
.... 

I am trying to process all the data from $a2 in +4 increments $a2[0+4] $a2[1+4] $a2[2+4] $a2[3+4]

UPD2:

I really don't need the variables $i and $j, I'm just trying to create a loop and found a suitable method on the internet

When I use

   for (($i = 0), ($j = 0); $i -lt 10; ($i++))
{
 $a2[4]
 $a2[5]
 $a2[6]
 $a2[7]

}

I get 10 times the data:

id2
title2
Description2
Rew2

I'd like to get one for the first time:

id2
title2
Description2
Rew2

For the second time:

id3
title3
Description3
Rew3

Third time:

id4
title4
Description4
Rew4

Fourth time:

id5
title5
Description5
Rew5

Fifth time:

id6
title6
Description6
Rew6

Sixth time:

id7
title7
Description7
Rew7

The seventh time:

id8
title8
Description8
Rew8

Eighth time:

id9
title9
Description9
Rew9

Ninth time:

id10
title10
Description10
Rew10

Tenth time:

id11
title11
Description11
Rew11

3 Answers 3

4

It seems what you're looking for is to increment by 4 on each loop iteration, so something like:

for ($i = 0; $i -lt $sample.Length; $i += 4) {
    [pscustomobject]@{
        id          = $sample[$i]
        title       = $sample[$i + 1]
        description = $sample[$i + 2]
        rew         = $sample[$i + 3]
    }
}

# Outputs:
#
# id  title  description  rew
# --  -----  -----------  ---
# id1 title1 Description1 Rew1
# id2 title2 Description2 Rew2
# id3 title3 Description3 Rew3
# id4 title4 Description4 Rew4
# id5 title5 Description5 Rew5

Where $sample is just the text sample you have provided turned into a string array with -split ($sample in this case could be the text you got from reading a file with Get-Content for example).

$sample = @'
id1
title1
Description1
Rew1
id2
title2
Description2
Rew2
id3
title3
Description3
Rew3
id4
title4
Description4
Rew4
id5
title5
Description5
Rew5
'@ -split '\r?\n'
Sign up to request clarification or add additional context in comments.

Comments

1

Ok, assuming you have an array $a2 with n elements, where n is a multiply of 4. For example:

# array a2 with the values
$a2 = @("id1", "title1", "desc1", "rew1", "id2", "title2", "desc2", "rew2");

Then you can iterate over the array like this:

for (($i = 0); $i -lt $a2.Length/4; ($i++))
{
    Write-Host("Iteration " + $i);
    $a2[$i*4+0]
    $a2[$i*4+1]
    $a2[$i*4+2]
    $a2[$i*4+3]
}

Output:

Iteration 0
id1
title1
desc1
rew1
Iteration 1
id2
title2
desc2
rew2

Comments

1

Let me offer a solution that showcases .., PowerShell's range operator:

Note: For conceptual clarity, I'm using $array rather than $ac2 as the variable assumed to contain the input array.

$chunkSize = 4
foreach ($chunkIndex in 0..($array.Count / $chunkSize - 1)) {
  $startNdx = $chunkIndex * $chunkSize # determine next start index
  $arrayChunk = $array[$startNdx..($startNdx+$chunkSize-1)] # extract next chunk
  "$arrayChunk" # diagnostic output, to show that the chunk was properly extracted.
  # ... work with the chunk here
}
  • $array.Count / $chunkSize calculates the number of "chunks" (batches), i.e. contiguous sub-arrays, to extract from the input array.

    • Note: This calculation assumes that the array size is an exact multiple of the chunk size.
      If this assumption cannot be made:
      • If you want to include remaining elements that form an incomplete chunk, use [Math]::Ceiling($array.Count / $chunkSize)

      • To exclude them, use [Math]::Floor($array.Count / $chunkSize)

  • The foreach loop then loops over the 0-based indices of the number of chunks to extract.

  • $startNdx = $chunkIndex * $chunkSize calculates the index at which the next sub-array to extract starts.

  • $startNdx..($startNdx+$chunkSize-1) then uses .. to generate a range of indices (integers) from the start index through the next $chunkSize ones, which causes[], PowerShell's index operator to return a new array comprising the referenced elements.

  • "$arrayChunk" stringifies and outputs each array chunk for diagnostic display output; PowerShell stringifies arrays by concatenating their elements with spaces, yielding the following:

      id1 title1 Description1 Rew1
      id2 title2 Description2 Rew2
      id3 title3 Description3 Rew3
      id4 title4 Description4 Rew4
      id5 title5 Description5 Rew5
    
  • As an aside:

    • If the elements of your array come from the lines of a file, you could use Get-Content's -ReadCount parameter to directly read the file in chunks of 4 lines; e.g.:

      Get-Content file.txt -ReadCount 4 | ForEach-Object { "$_" }
      
    • See the bottom section for a feature request to provide this functionality as a general feature.


If, rather than processing each chunk inside the foreach loop, you prefer to collect all chunks up front, for later processing, in an array of arrays (jagged array):

$chunkSize = 4
[array] $arrayChunks = 
  foreach ($chunkIndex in 0..($array.Count / $chunkSize-1)) {
    $startNdx = $chunkIndex * $chunkSize # determine next start index
    # extract the next chunk and output it *as a whole*, via the unary form of 
    # the "," operator
    , $array[$startNdx..($startNdx+$chunkSize-1)] 
  }
  • Note the use of the unary form of , the "comma" (array constructor) operator, to wrap each chunk in an aux. array that prevents the chunk's elements from being output individually; see this answer for details.

  • To visualize the resulting array chunks using the same technique as above, run
    $arrayChunks | ForEach-Object { "$_" }
    or foreach ($chunk in $arrayChunks) { "$chunk" }


Finally, it would be nice if PowerShell had built-in support for chunking (batching) (in a generalized manner, not just with Get-Content):

  • GitHub issue #8270 requests just that, by suggesting that a -ReadCount parameter be added to the general-purpose Select-Object cmdlet too.

  • In the meantime, this answer provides custom function Select-Chunk that fills the gap; with it, your task could be simplified to:

    $array | Select-Chunk 4 | ForEach-Object { "$_" }
    

Comments

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.