Home > front end >  Powershell: how to turn an array of objects into an array of integers?
Powershell: how to turn an array of objects into an array of integers?

Time:09-26

I create an array of objects that hold the lengths of files with this command:

$lengths = dir -File | Sort-Object -Descending | Select-Object Length -First 5

However, I want this to be an array of integers, not objects, so I can edit the values easily. How can I convert this $lengths object array into an integer array?

Thank You! :)

CodePudding user response:

The answer was provided in comments but to give it closure, you can expand the values of the objects using Select-Object -ExpandProperty. It's worth noting that your Sort-Object statement is not actually sorting by Length unless you specify the property to be sorted:

$length = dir -File | Sort-Object Length -Descending | Select-Object -ExpandProperty Length -First 5

Personal preference to expand the values, you can use ForEach-Object, the syntax is far easier in my opinion but there is no -First X here:

$length = dir -File | ForEach-Object Length | Sort-Object -Descending

$length type will be object[] (object array) even though it will contain an array of int64 values, this is default type for arrays in PowerShell, you can however provide a desired output type either by type casting or hard typing. Looking into the Cast Operator [..] is a good starting point.

# type casting
$length = [Int64[]] (dir -File | ....)

# hard typing
[Int64[]] $length = dir -File | ....

For the latter, $length is constrained to be assigned int64 values or values that can be type coerced to int64, i.e.:

[int64[]] $length = 0..10

# can be assigned an `int32` and the array element will be converted to `int64`
$length = 1
$length[0].GetType() # => `int64`

# can be assigned a `string` which contains for example a decimal value
$length = '1.1', 2
# gets converted to int64 (no longer a decimal value)
$length[0] # => 1

# cannot be assigned a `string` which does not contain a type of numeric value
$length = 1, 'hello' # => ...Cannot convert value "hello" to type "System.Int64"...

While the former only enforces the type of the array elements however a new array of different type can be assigned:

$length    = [int64[]] (0..10)
$length[0] = 'hello' # => ...Cannot convert value "hello" to type "System.Int64"...

$length = 'new', 'object', 'array' # succeeds

CodePudding user response:

Unfortunately, you can't use Memeber Access Enumeration for Length because it's also a property of the collection (Unlike, for example, (gci -af).LastwriteTime). But another way to obtain your desired array is:

$Length = (gci -af).Foreach({$_.Length}) | sort -Descending

Without casting, $Length is the generic object array:

PS > $Length.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]

But all its elements are the same type:

PS > ($Length | gm).TypeName | select -Unique
System.Int64
  • Related