TechTalkz.com Logo Ask the Experts!

Go Back   TechTalkz.com Technology & Computer Troubleshooting Forums > Tech Support Archives > Microsoft > Microsoft Windows Powershell

Converting array elements between types

Microsoft Windows Powershell

 
 
Thread Tools Display Modes
Unread 01-03-2008, 12:29 AM   #1
Kryten
Guest
 
Posts: n/a
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

 
Unread 01-03-2008, 01:31 AM   #2
Oisin (x0n) Grehan [MVP]
Guest
 
Posts: n/a
Re: Converting array elements between types

On Feb 29, 7:22*pm, Kryten <Kryte...@googlemail.com> wrote:
> 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
 
Unread 01-03-2008, 01:31 AM   #3
Kryten
Guest
 
Posts: n/a
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
 
Unread 01-03-2008, 01:31 AM   #4
Kiron
Guest
 
Posts: n/a
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
 
Unread 01-03-2008, 09:18 AM   #5
Kryten
Guest
 
Posts: n/a
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
> ,$a | gm


rather than

> $a | gm


Why isn't the comma'd version implied?


 
Unread 01-03-2008, 05:27 PM   #6
Oisin (x0n) Grehan [MVP]
Guest
 
Posts: n/a
Re: Converting array elements between types

On Mar 1, 3:57*am, Kryten <Kryte...@googlemail.com> wrote:
> 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
>
> > ,$a | gm

>
> rather than
>
> > $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
 
Unread 01-03-2008, 07:24 PM   #7
Kiron
Guest
 
Posts: n/a
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
 
 

Thread Tools
Display Modes



< Home - Windows Help - MS Office Help - Hardware Support >


New To Site? Need Help?

All times are GMT. The time now is 08:35 AM.


vBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO
Copyright © 2005-2013, TechTalkz.com. All Rights Reserved - Privacy Policy
Valid XHTML 1.0 Transitional