Windows Vista Forums
Vista Forums Home Join Vista Forums Donate Vista Tutorials Tags

Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
Register at Vista forums...the world biggest Windows Vista resource Join Vista Forums Now

Go Back   Vista Forums > Microsoft Technical Newsgroups > PowerShell

Converting array elements between types

Update your Vista Drivers Update Your Drivers Now!!
Closed Thread
 
Thread Tools Display Modes
Old 02-29-2008   #1 (permalink)
Kryten
Guest


 

Converting array elements between types

Hi,

Just my inexperience and lack of knowledge, but could someone explain
why this is so and what is best practice to overcome this situation,
please.

PS D:\POSH> [string]$a = 12345
PS D:\POSH> $a
12345
PS D:\POSH> $a.gettype()

IsPublic IsSerial Name BaseType
-------- -------- ----
--------
True True String
System.Object

## Okay so $a is a string
## I can access individual elements with:-
PS D:\POSH> $a[3]
4
PS D:\POSH>$a[4]
5

So, the question is what if I want to add $a[4] to $a[3] for a total
of [integer] 9

If I try to create a new variable as an integer to hold $a[4] :-

PS D:\POSH> [int]$b = $a[4]
PS D:\POSH> $b
53

So why is $b exposing a value of 53?

I had expected PS to realise that I was trying to cast $b as an
integer, see that $a[4] was actually a valid number and allow me to
make $b worth [int]5. Can't seem to find any obvious members which
will convert the type for me, almost like a $a.ToInteger() to
counterpoint the $a.ToString() method!

I realise that the answer is probably basic but I'd really appreciate
a steer on how best to deal with this problem, unfortunately all the
arrays that my script needs to deal with are currently being cast as
[string] to begin with, is that a showstopper for future numerical
calculations on the elements?

Thanks,
Stuart


My System SpecsSystem Spec
Old 02-29-2008   #2 (permalink)
Oisin (x0n) Grehan [MVP]
Guest


 

Re: Converting array elements between types

On Feb 29, 7:22*pm, Kryten <Kryte...@xxxxxx> wrote:
Quote:

> Hi,
>
> Just my inexperience and lack of knowledge, but could someone explain
> why this is so and what is best practice to overcome this situation,
> please.
>
> PS D:\POSH> [string]$a = 12345
> PS D:\POSH> $a
> 12345
> PS D:\POSH> $a.gettype()
>
> IsPublic IsSerial Name * * * * * * * * * * * * ** * * * * BaseType
> -------- -------- ----
> --------
> True * * True * * String
> System.Object
>
> ## Okay so $a is a string
> ## I can access individual elements with:-
> PS D:\POSH> $a[3]
> 4
> PS D:\POSH>$a[4]
> 5
>
> So, the question is what if I want to add $a[4] to $a[3] for a total
> of [integer] 9
>
> If I try to create a new variable as an integer to hold $a[4] :-
>
> PS D:\POSH> [int]$b = $a[4]
> PS D:\POSH> $b
> 53
>
> So why is $b exposing a value of 53?
>
> I had expected PS to realise that I was trying to cast $b as an
> integer, see that $a[4] was actually a valid number and allow me to
> make $b worth [int]5. Can't seem to find any obvious members which
> will convert the type for me, almost like a $a.ToInteger() to
> counterpoint the $a.ToString() method!
>
> I realise that the answer is probably basic but I'd really appreciate
> a steer on how best to deal with this problem, unfortunately all the
> arrays that my script needs to deal with are currently being cast as
> [string] to begin with, is that a showstopper for future numerical
> calculations on the elements?
>
> Thanks,
> Stuart
Hi Stuart,

What you really need is:

ps> $a = "12345"
ps> [int]:arse($a[4]) + [int]:arse($a[2])
8

It's the difference between casting and parsing. $a[4] is an object of
type [char]. Casting an object that is a [char] (a single character)
to [int] (a number) converts it into the ASCII representation of the
character.

Hope this helps,

- Oisin
My System SpecsSystem Spec
Old 02-29-2008   #3 (permalink)
Kryten
Guest


 

Re: Converting array elements between types

Hi Oisin,

Got It!
Thats much clearer in my mind now.

Correct me if I'm wrong but your suggesting using the static member
(: "parse" to effectively re-parse the
element and in so doing re-cast it as an integer?

Well it works and gives me the desired effect...brilliant stuff.

Thanks again,
Stuart
My System SpecsSystem Spec
Old 02-29-2008   #4 (permalink)
Kiron
Guest


 

Re: Converting array elements between types

More ideas...

[string]$a = 12345
# too long
[int]$a[3].ToString() + [int]$a[4].ToString()
# shorter
[int][string]$a[3] + [int][string]$a[4]
# shortest
[int]"$($a[3])" + [int]"$($a[4])"

# create a [int[]]
$b = [char[]]$a|%{[int]"$_"}
# optimal
$b[3] + $b[4]

--
Kiron
My System SpecsSystem Spec
Old 03-01-2008   #5 (permalink)
Kryten
Guest


 

Re: Converting array elements between types

Kiron, Oisin,

Awesome guys, more than pointers these tips drop me right at the door!

I also noticed in "Lee Holmes' PowerShell Cookbook" a tip for
simplifying the arrays that I'm trying
to deal with using the SYSTEM.COLLECTIONS.ARRAYLIST class.

Eg
PS D:\POSH> $a = new-object system.collections.arraylist
PS D:\POSH> $a.add("Hello")
0 ## Echoes back the element used to store the entry
PS D:\POSH> $a.add("Good Evening")
1
PS D:\POSH> $a.add("And Welcome")
2
PS D:\POSH> $a
Hello
Good Evening
And Welcome
PS D:\POSH> $a.RemoveAt(0)
PS D:\POSH> $a
Good Evening
And Welcome
PS D:\POSH>

Can't recommend that book highly enough, I got my £30 worth out of it
in the first week.

Cheers,
Stuart

PS - Can someone tell me why adding a comma to my object before
passing it to get-member gives me the props and methods that
I can "actually" use. Without the comma you seem to get methods that
you can't use, which for me has been a very timeconsuming
lesson to learn!

Eg
Quote:

> ,$a | gm
rather than
Quote:

> $a | gm
Why isn't the comma'd version implied?


My System SpecsSystem Spec
Old 03-01-2008   #6 (permalink)
Oisin (x0n) Grehan [MVP]
Guest


 

Re: Converting array elements between types

On Mar 1, 3:57*am, Kryten <Kryte...@xxxxxx> wrote:
Quote:

> Kiron, Oisin,
>
> Awesome guys, more than pointers these tips drop me right at the door!
>
> I also noticed in "Lee Holmes' PowerShell Cookbook" a tip for
> simplifying the arrays that I'm trying
> to deal with using the SYSTEM.COLLECTIONS.ARRAYLIST class.
>
> Eg
> PS D:\POSH> $a = new-object system.collections.arraylist
> PS D:\POSH> $a.add("Hello")
> 0 * ## Echoes back the element used to store the entry
> PS D:\POSH> $a.add("Good Evening")
> 1
> PS D:\POSH> $a.add("And Welcome")
> 2
> PS D:\POSH> $a
> Hello
> Good Evening
> And Welcome
> PS D:\POSH> $a.RemoveAt(0)
> PS D:\POSH> $a
> Good Evening
> And Welcome
> PS D:\POSH>
>
> Can't recommend that book highly enough, I got my £30 worth out of it
> in the first week.
>
> Cheers,
> Stuart
>
> PS - Can someone tell me why adding a comma to my object before
> passing it to get-member gives me the props and methods that
> I can "actually" use. Without the comma you seem to get methods that
> you can't use, which for me has been a very timeconsuming
> lesson to learn!
>
> Eg
>
Quote:

> > ,$a | gm
>
> rather than
>
Quote:

> > $a | gm
>
> Why isn't the comma'd version implied?
Some facts:

$a is a [string], but $a can also be a array of [char].

When you use:

,$a | gm

You are not actually getting the members from the array of char
( expressed as [char[]] ) - instead, you are getting the members from
an array of [object]. The comma is an array constructor, and what that
construct is actually doing is creating an [object] array of length 1.
You can verify this by:

PS E:\projects\powershell> (,$a).gettype()

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

PS E:\projects\powershell> (,$a).length
1

So, if you _really_ wanted to see the members of the char array
representing $a, you would use a cast:

PS E:\projects\powershell> ([char[]]$a).gettype()

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

and to get the length:

PS E:\projects\powershell> ([char[]]$a).length
5

as you can see, this is the expected length for the string "12345".
Another trick is using the "(" and ")" to create a subexpression to
force the cast to occur first before the call to gettype(). Without
the brackets, the return of gettype() gets casted (and fails).

Hope this helps.

- Oisin
My System SpecsSystem Spec
Old 03-01-2008   #7 (permalink)
Kiron
Guest


 

Re: Converting array elements between types

I'm not as erudite on the subject as others are, but I'll try to explain.
When you pipe an array or collection to Get-Member the array is unraveled and the Cmdlet outputs the members for each of the types -if more than one- of the elements in the array or collection.
By preceding the array or collection with the Comma operator before piping it to Get-Member a singleton -a one element array- containing the original array or collection as its only element is piped. When the singleton is unraveled Get-Member receives the original array or collection intact and outputs its members.
Get-Member is not limited to piped input, you can pass the array intact to Get-Member through its -inputObject and should get the array's, or collection's, members:

# create a mixed array
$a = 1, 'a', 3, 'b', (date), 5, 'c', 7, 'd', 9

# $a is an [object[]]
$a.getType().fullName

# array is unraveled
$a | gm

# preceded with the Comma operator
# a new singleton array is piped.
# Get-Member uravels the singleton
# and outputs the original array's,
# or collection's, members
,$a | gm

# without the Comma operator
Get-Member -inputObject $a

# shorter
gm -i $a

--
Kiron
My System SpecsSystem Spec
Closed Thread

Thread Tools
Display Modes



Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: help needed converting c# array declarations to work inpowershell Oisin (x0n) Grehan [MVP] PowerShell 0 06-04-2008 08:00 AM
Command return types - an array, or not? Michael Lewis PowerShell 2 12-07-2007 01:58 AM
number of elements in array Frank PowerShell 2 05-25-2007 08:21 AM
re-ordering elements in an array? Marco Shaw PowerShell 7 11-10-2006 04:25 PM


Vistax64.com is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media 2005-2008

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51