Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract a range from a collection in powershell?

I have a large set of items and I want to extract items from it. I need to skip some items from start and some from end.

The following example is simplified.

I first tried to extract the bounding elements:

> ("a", "b", "c", "d", "e")[1,-2]
b
d  

This works as expected.

However when I tried to extract whole range it returns something else than I want (in contrast with Python's ['a', 'b', 'c', 'd', 'e'][1:-1] which works well).

> ("a", "b", "c", "d", "e")[1..-2]
b
a
e
d  

It loops the other way round. How to change the direction of the loop?

I want to get: b c d.

Is there a solution without using the real length of the collection?

like image 469
TN. Avatar asked Jul 11 '12 09:07

TN.


People also ask

How do I read an array value in PowerShell?

The values stored in the array are delimited with a comma and separated from the variable name by the assignment operator ( = ). The comma can also be used to initialize a single item array by placing the comma before the single item. You can also create and initialize an array by using the range operator ( .. ).

What is @{} in PowerShell?

@{} in PowerShell defines a hashtable, a data structure for mapping unique keys to values (in other languages this data structure is called "dictionary" or "associative array"). @{} on its own defines an empty hashtable, that can then be filled with values, e.g. like this: $h = @{} $h['a'] = 'foo' $h['b'] = 'bar'

How do you access array elements in PowerShell?

The array elements are accessed through the index. Array indices are 0-based; that is, they start from 0 to arrayRefVar. length-1.

What is a collection in PowerShell?

Collections (Arrays) Collections are everywhere in PowerShell; they are the most prevalent of all its data structures. Cmdlets and pipes let you pass around objects, but keep in mind that they usually pass around objects (plural), not just an object (singular).


3 Answers

1..-2 will not count from the first item until two items from the end. Save the array to a variable and specify the upper bound by calculating the array length minus the items from the end.

$a = "a", "b", "c", "d", "e"
$a[1..($a.length-2)]
like image 66
Shay Levy Avatar answered Oct 02 '22 00:10

Shay Levy


Since the range operator does not do what you require, a simple pipeline can accomplish the task at hand, though this will likely impact performance for a large collection.

Start with a collection and the number of elements to trim from top and from bottom:

$a = "a", "b", "c", "d", "e"
($fromTop,$fromBottom) = 1, 2

Use this...

$a | select -skip $fromTop | select -skip $fromBottom -last 1000000

...or, if you have PSCX installed, this more concise and elegant sequence:

$a | skip -first $fromTop -last $fromBottom

Both of those return b c without explicitly using the length property. Adjust the two parameters to tailor the output to different ranges.

like image 33
Michael Sorens Avatar answered Oct 01 '22 23:10

Michael Sorens


To just remov the first two ones you can do that :

$null,$null,$a = "a", "b", "c", "d", "e"
like image 24
JPBlanc Avatar answered Oct 01 '22 22:10

JPBlanc