powershell arrays add-member - looking for elegant code
I have a pretty basic PowerShell array: $TestArray with 2 text columns: Price and TimeStamp (that's the way I get them, nothing to be done about this):
Price TimeStamp
----- ----------------
0.0567 1542056680.72746
0.0567 1542056650.34414
0.0555 1542056197.46668
0.0551 1542056167.28967
I would like, in a single PowerShell line to add a rounded Time2
value
$Time2 = [math]::Round($TestArray.TimeStamp)
The code I am thinking of is:
$TestArray | Add-Member -Name Time2 -MemberType NoteProperty -Value [math]::Round($Table.TimeStamp)
Of course, I can do a ForEach loop; it would take care of it easily, but I would like to achieve this in this single line of code.
Any idea ?
Cheers,
Philippe
arrays powershell pipeline
add a comment |
I have a pretty basic PowerShell array: $TestArray with 2 text columns: Price and TimeStamp (that's the way I get them, nothing to be done about this):
Price TimeStamp
----- ----------------
0.0567 1542056680.72746
0.0567 1542056650.34414
0.0555 1542056197.46668
0.0551 1542056167.28967
I would like, in a single PowerShell line to add a rounded Time2
value
$Time2 = [math]::Round($TestArray.TimeStamp)
The code I am thinking of is:
$TestArray | Add-Member -Name Time2 -MemberType NoteProperty -Value [math]::Round($Table.TimeStamp)
Of course, I can do a ForEach loop; it would take care of it easily, but I would like to achieve this in this single line of code.
Any idea ?
Cheers,
Philippe
arrays powershell pipeline
why the single line of code requirement? [frown] a foreach loop is often far faster than anything that uses the pipeline.
– Lee_Dailey
Nov 12 '18 at 21:33
Saving code length to add clarity for further maintenance (on this example, in real life, where I have no performance issues, I save overall 1 full page of code)
– Philippe
Nov 12 '18 at 23:01
thanks for the rationale. [grin] it's wrong, but that is OK. take a look at the code posted by mklement0 for a thorough refutation of "too long". as for maintainability ... laying the steps out clearly is FAR more maintainable than a more-than-simple pipeline. ///// still, as my papa said "if we were all the same, the world would be boring as heck!" [grin]
– Lee_Dailey
Nov 12 '18 at 23:48
add a comment |
I have a pretty basic PowerShell array: $TestArray with 2 text columns: Price and TimeStamp (that's the way I get them, nothing to be done about this):
Price TimeStamp
----- ----------------
0.0567 1542056680.72746
0.0567 1542056650.34414
0.0555 1542056197.46668
0.0551 1542056167.28967
I would like, in a single PowerShell line to add a rounded Time2
value
$Time2 = [math]::Round($TestArray.TimeStamp)
The code I am thinking of is:
$TestArray | Add-Member -Name Time2 -MemberType NoteProperty -Value [math]::Round($Table.TimeStamp)
Of course, I can do a ForEach loop; it would take care of it easily, but I would like to achieve this in this single line of code.
Any idea ?
Cheers,
Philippe
arrays powershell pipeline
I have a pretty basic PowerShell array: $TestArray with 2 text columns: Price and TimeStamp (that's the way I get them, nothing to be done about this):
Price TimeStamp
----- ----------------
0.0567 1542056680.72746
0.0567 1542056650.34414
0.0555 1542056197.46668
0.0551 1542056167.28967
I would like, in a single PowerShell line to add a rounded Time2
value
$Time2 = [math]::Round($TestArray.TimeStamp)
The code I am thinking of is:
$TestArray | Add-Member -Name Time2 -MemberType NoteProperty -Value [math]::Round($Table.TimeStamp)
Of course, I can do a ForEach loop; it would take care of it easily, but I would like to achieve this in this single line of code.
Any idea ?
Cheers,
Philippe
arrays powershell pipeline
arrays powershell pipeline
edited Nov 12 '18 at 20:44
Mathias R. Jessen
58.3k463109
58.3k463109
asked Nov 12 '18 at 20:42
PhilippePhilippe
276
276
why the single line of code requirement? [frown] a foreach loop is often far faster than anything that uses the pipeline.
– Lee_Dailey
Nov 12 '18 at 21:33
Saving code length to add clarity for further maintenance (on this example, in real life, where I have no performance issues, I save overall 1 full page of code)
– Philippe
Nov 12 '18 at 23:01
thanks for the rationale. [grin] it's wrong, but that is OK. take a look at the code posted by mklement0 for a thorough refutation of "too long". as for maintainability ... laying the steps out clearly is FAR more maintainable than a more-than-simple pipeline. ///// still, as my papa said "if we were all the same, the world would be boring as heck!" [grin]
– Lee_Dailey
Nov 12 '18 at 23:48
add a comment |
why the single line of code requirement? [frown] a foreach loop is often far faster than anything that uses the pipeline.
– Lee_Dailey
Nov 12 '18 at 21:33
Saving code length to add clarity for further maintenance (on this example, in real life, where I have no performance issues, I save overall 1 full page of code)
– Philippe
Nov 12 '18 at 23:01
thanks for the rationale. [grin] it's wrong, but that is OK. take a look at the code posted by mklement0 for a thorough refutation of "too long". as for maintainability ... laying the steps out clearly is FAR more maintainable than a more-than-simple pipeline. ///// still, as my papa said "if we were all the same, the world would be boring as heck!" [grin]
– Lee_Dailey
Nov 12 '18 at 23:48
why the single line of code requirement? [frown] a foreach loop is often far faster than anything that uses the pipeline.
– Lee_Dailey
Nov 12 '18 at 21:33
why the single line of code requirement? [frown] a foreach loop is often far faster than anything that uses the pipeline.
– Lee_Dailey
Nov 12 '18 at 21:33
Saving code length to add clarity for further maintenance (on this example, in real life, where I have no performance issues, I save overall 1 full page of code)
– Philippe
Nov 12 '18 at 23:01
Saving code length to add clarity for further maintenance (on this example, in real life, where I have no performance issues, I save overall 1 full page of code)
– Philippe
Nov 12 '18 at 23:01
thanks for the rationale. [grin] it's wrong, but that is OK. take a look at the code posted by mklement0 for a thorough refutation of "too long". as for maintainability ... laying the steps out clearly is FAR more maintainable than a more-than-simple pipeline. ///// still, as my papa said "if we were all the same, the world would be boring as heck!" [grin]
– Lee_Dailey
Nov 12 '18 at 23:48
thanks for the rationale. [grin] it's wrong, but that is OK. take a look at the code posted by mklement0 for a thorough refutation of "too long". as for maintainability ... laying the steps out clearly is FAR more maintainable than a more-than-simple pipeline. ///// still, as my papa said "if we were all the same, the world would be boring as heck!" [grin]
– Lee_Dailey
Nov 12 '18 at 23:48
add a comment |
3 Answers
3
active
oldest
votes
Mathias R. Jessen's answer directly solves your problem, by creating a script property (type ScriptProperty
) that dynamically calculates its value from the enclosing object's .TimeStamp
property.
- The advantage of this approach is that even later changes to
.TimeStamp
will correctly be reflected in.Time2
, albeit at the cost of having to calculate the value on every access.
Manuel Batsching's answer offers a Select-Object
-based alternative that creates static note properties (type NoteProperty
), as you've originally attempted yourself.
- The advantage of this approach is that you incur the cost of calculation only once, but later changes to
.TimeStamp
won't be reflected in.Time2
.
To offer faster PSv5+ alternatives (a single method call each, spread across multiple lines for readability):
# ScriptProperty - dynamic
$TestArray.ForEach(
$_.psobject.properties.Add(
[psscriptproperty]::new('Time2', [math]::Round($this.TimeStamp) )
)
)
# NoteProperty - static
$TestArray.ForEach(
$_.psobject.properties.Add(
[psnoteproperty]::new('Time2', [math]::Round($_.TimeStamp))
)
)
The above solutions use the PSv4+ .ForEach()
collection method and the PSv5+ static ::new()
type method for calling constructors.
Finally, re one-liner:
The following foreach
-loop based note-property solution would have solved your problem too, and would have been faster; while it is spread across multiple lines for readability here, it also works as a one-liner:
foreach ($el in $TestArray)
Add-Member -InputObject $el -Name Time2 -MemberType NoteProperty `
-Value ([math]::Round($el.TimeStamp))
Generally, while the pipeline often enables more elegant, single-command solution, that - unfortunately - comes at the expense of performance.
add a comment |
Alternatively you can achieve the same with Select-Object
and a custom property:
$TestArray | Select-Object *,@ n='Time2';e= [math]::Round($_.TimeStamp)
Very clear and useful comments Manuel. I'll finally go with your last alternative, because I need to do further comparaisons and maths on my TimeStamp value - therefore it is preferable to have it as static NoteProperty type.
– Philippe
Nov 12 '18 at 22:57
add a comment |
Change the member type to ScriptProperty
and refer to the individual array item as $this
:
$TestArray |Add-Member Time2 -Value [math]::Round($this.Timestamp) -MemberType ScriptProperty
Worth noting that in this example, the pipeline itself acts as a foreach
loop, unravelling the array and binding each individual item to Add-Member
1
I had tried with $this but without changing the -MemberType to ScriptProperty !
– Philippe
Nov 12 '18 at 21:02
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53269794%2fpowershell-arrays-add-member-looking-for-elegant-code%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Mathias R. Jessen's answer directly solves your problem, by creating a script property (type ScriptProperty
) that dynamically calculates its value from the enclosing object's .TimeStamp
property.
- The advantage of this approach is that even later changes to
.TimeStamp
will correctly be reflected in.Time2
, albeit at the cost of having to calculate the value on every access.
Manuel Batsching's answer offers a Select-Object
-based alternative that creates static note properties (type NoteProperty
), as you've originally attempted yourself.
- The advantage of this approach is that you incur the cost of calculation only once, but later changes to
.TimeStamp
won't be reflected in.Time2
.
To offer faster PSv5+ alternatives (a single method call each, spread across multiple lines for readability):
# ScriptProperty - dynamic
$TestArray.ForEach(
$_.psobject.properties.Add(
[psscriptproperty]::new('Time2', [math]::Round($this.TimeStamp) )
)
)
# NoteProperty - static
$TestArray.ForEach(
$_.psobject.properties.Add(
[psnoteproperty]::new('Time2', [math]::Round($_.TimeStamp))
)
)
The above solutions use the PSv4+ .ForEach()
collection method and the PSv5+ static ::new()
type method for calling constructors.
Finally, re one-liner:
The following foreach
-loop based note-property solution would have solved your problem too, and would have been faster; while it is spread across multiple lines for readability here, it also works as a one-liner:
foreach ($el in $TestArray)
Add-Member -InputObject $el -Name Time2 -MemberType NoteProperty `
-Value ([math]::Round($el.TimeStamp))
Generally, while the pipeline often enables more elegant, single-command solution, that - unfortunately - comes at the expense of performance.
add a comment |
Mathias R. Jessen's answer directly solves your problem, by creating a script property (type ScriptProperty
) that dynamically calculates its value from the enclosing object's .TimeStamp
property.
- The advantage of this approach is that even later changes to
.TimeStamp
will correctly be reflected in.Time2
, albeit at the cost of having to calculate the value on every access.
Manuel Batsching's answer offers a Select-Object
-based alternative that creates static note properties (type NoteProperty
), as you've originally attempted yourself.
- The advantage of this approach is that you incur the cost of calculation only once, but later changes to
.TimeStamp
won't be reflected in.Time2
.
To offer faster PSv5+ alternatives (a single method call each, spread across multiple lines for readability):
# ScriptProperty - dynamic
$TestArray.ForEach(
$_.psobject.properties.Add(
[psscriptproperty]::new('Time2', [math]::Round($this.TimeStamp) )
)
)
# NoteProperty - static
$TestArray.ForEach(
$_.psobject.properties.Add(
[psnoteproperty]::new('Time2', [math]::Round($_.TimeStamp))
)
)
The above solutions use the PSv4+ .ForEach()
collection method and the PSv5+ static ::new()
type method for calling constructors.
Finally, re one-liner:
The following foreach
-loop based note-property solution would have solved your problem too, and would have been faster; while it is spread across multiple lines for readability here, it also works as a one-liner:
foreach ($el in $TestArray)
Add-Member -InputObject $el -Name Time2 -MemberType NoteProperty `
-Value ([math]::Round($el.TimeStamp))
Generally, while the pipeline often enables more elegant, single-command solution, that - unfortunately - comes at the expense of performance.
add a comment |
Mathias R. Jessen's answer directly solves your problem, by creating a script property (type ScriptProperty
) that dynamically calculates its value from the enclosing object's .TimeStamp
property.
- The advantage of this approach is that even later changes to
.TimeStamp
will correctly be reflected in.Time2
, albeit at the cost of having to calculate the value on every access.
Manuel Batsching's answer offers a Select-Object
-based alternative that creates static note properties (type NoteProperty
), as you've originally attempted yourself.
- The advantage of this approach is that you incur the cost of calculation only once, but later changes to
.TimeStamp
won't be reflected in.Time2
.
To offer faster PSv5+ alternatives (a single method call each, spread across multiple lines for readability):
# ScriptProperty - dynamic
$TestArray.ForEach(
$_.psobject.properties.Add(
[psscriptproperty]::new('Time2', [math]::Round($this.TimeStamp) )
)
)
# NoteProperty - static
$TestArray.ForEach(
$_.psobject.properties.Add(
[psnoteproperty]::new('Time2', [math]::Round($_.TimeStamp))
)
)
The above solutions use the PSv4+ .ForEach()
collection method and the PSv5+ static ::new()
type method for calling constructors.
Finally, re one-liner:
The following foreach
-loop based note-property solution would have solved your problem too, and would have been faster; while it is spread across multiple lines for readability here, it also works as a one-liner:
foreach ($el in $TestArray)
Add-Member -InputObject $el -Name Time2 -MemberType NoteProperty `
-Value ([math]::Round($el.TimeStamp))
Generally, while the pipeline often enables more elegant, single-command solution, that - unfortunately - comes at the expense of performance.
Mathias R. Jessen's answer directly solves your problem, by creating a script property (type ScriptProperty
) that dynamically calculates its value from the enclosing object's .TimeStamp
property.
- The advantage of this approach is that even later changes to
.TimeStamp
will correctly be reflected in.Time2
, albeit at the cost of having to calculate the value on every access.
Manuel Batsching's answer offers a Select-Object
-based alternative that creates static note properties (type NoteProperty
), as you've originally attempted yourself.
- The advantage of this approach is that you incur the cost of calculation only once, but later changes to
.TimeStamp
won't be reflected in.Time2
.
To offer faster PSv5+ alternatives (a single method call each, spread across multiple lines for readability):
# ScriptProperty - dynamic
$TestArray.ForEach(
$_.psobject.properties.Add(
[psscriptproperty]::new('Time2', [math]::Round($this.TimeStamp) )
)
)
# NoteProperty - static
$TestArray.ForEach(
$_.psobject.properties.Add(
[psnoteproperty]::new('Time2', [math]::Round($_.TimeStamp))
)
)
The above solutions use the PSv4+ .ForEach()
collection method and the PSv5+ static ::new()
type method for calling constructors.
Finally, re one-liner:
The following foreach
-loop based note-property solution would have solved your problem too, and would have been faster; while it is spread across multiple lines for readability here, it also works as a one-liner:
foreach ($el in $TestArray)
Add-Member -InputObject $el -Name Time2 -MemberType NoteProperty `
-Value ([math]::Round($el.TimeStamp))
Generally, while the pipeline often enables more elegant, single-command solution, that - unfortunately - comes at the expense of performance.
edited Nov 13 '18 at 4:56
answered Nov 12 '18 at 22:17
mklement0mklement0
135k21252289
135k21252289
add a comment |
add a comment |
Alternatively you can achieve the same with Select-Object
and a custom property:
$TestArray | Select-Object *,@ n='Time2';e= [math]::Round($_.TimeStamp)
Very clear and useful comments Manuel. I'll finally go with your last alternative, because I need to do further comparaisons and maths on my TimeStamp value - therefore it is preferable to have it as static NoteProperty type.
– Philippe
Nov 12 '18 at 22:57
add a comment |
Alternatively you can achieve the same with Select-Object
and a custom property:
$TestArray | Select-Object *,@ n='Time2';e= [math]::Round($_.TimeStamp)
Very clear and useful comments Manuel. I'll finally go with your last alternative, because I need to do further comparaisons and maths on my TimeStamp value - therefore it is preferable to have it as static NoteProperty type.
– Philippe
Nov 12 '18 at 22:57
add a comment |
Alternatively you can achieve the same with Select-Object
and a custom property:
$TestArray | Select-Object *,@ n='Time2';e= [math]::Round($_.TimeStamp)
Alternatively you can achieve the same with Select-Object
and a custom property:
$TestArray | Select-Object *,@ n='Time2';e= [math]::Round($_.TimeStamp)
answered Nov 12 '18 at 21:06
Manuel BatschingManuel Batsching
976412
976412
Very clear and useful comments Manuel. I'll finally go with your last alternative, because I need to do further comparaisons and maths on my TimeStamp value - therefore it is preferable to have it as static NoteProperty type.
– Philippe
Nov 12 '18 at 22:57
add a comment |
Very clear and useful comments Manuel. I'll finally go with your last alternative, because I need to do further comparaisons and maths on my TimeStamp value - therefore it is preferable to have it as static NoteProperty type.
– Philippe
Nov 12 '18 at 22:57
Very clear and useful comments Manuel. I'll finally go with your last alternative, because I need to do further comparaisons and maths on my TimeStamp value - therefore it is preferable to have it as static NoteProperty type.
– Philippe
Nov 12 '18 at 22:57
Very clear and useful comments Manuel. I'll finally go with your last alternative, because I need to do further comparaisons and maths on my TimeStamp value - therefore it is preferable to have it as static NoteProperty type.
– Philippe
Nov 12 '18 at 22:57
add a comment |
Change the member type to ScriptProperty
and refer to the individual array item as $this
:
$TestArray |Add-Member Time2 -Value [math]::Round($this.Timestamp) -MemberType ScriptProperty
Worth noting that in this example, the pipeline itself acts as a foreach
loop, unravelling the array and binding each individual item to Add-Member
1
I had tried with $this but without changing the -MemberType to ScriptProperty !
– Philippe
Nov 12 '18 at 21:02
add a comment |
Change the member type to ScriptProperty
and refer to the individual array item as $this
:
$TestArray |Add-Member Time2 -Value [math]::Round($this.Timestamp) -MemberType ScriptProperty
Worth noting that in this example, the pipeline itself acts as a foreach
loop, unravelling the array and binding each individual item to Add-Member
1
I had tried with $this but without changing the -MemberType to ScriptProperty !
– Philippe
Nov 12 '18 at 21:02
add a comment |
Change the member type to ScriptProperty
and refer to the individual array item as $this
:
$TestArray |Add-Member Time2 -Value [math]::Round($this.Timestamp) -MemberType ScriptProperty
Worth noting that in this example, the pipeline itself acts as a foreach
loop, unravelling the array and binding each individual item to Add-Member
Change the member type to ScriptProperty
and refer to the individual array item as $this
:
$TestArray |Add-Member Time2 -Value [math]::Round($this.Timestamp) -MemberType ScriptProperty
Worth noting that in this example, the pipeline itself acts as a foreach
loop, unravelling the array and binding each individual item to Add-Member
answered Nov 12 '18 at 20:50
Mathias R. JessenMathias R. Jessen
58.3k463109
58.3k463109
1
I had tried with $this but without changing the -MemberType to ScriptProperty !
– Philippe
Nov 12 '18 at 21:02
add a comment |
1
I had tried with $this but without changing the -MemberType to ScriptProperty !
– Philippe
Nov 12 '18 at 21:02
1
1
I had tried with $this but without changing the -MemberType to ScriptProperty !
– Philippe
Nov 12 '18 at 21:02
I had tried with $this but without changing the -MemberType to ScriptProperty !
– Philippe
Nov 12 '18 at 21:02
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53269794%2fpowershell-arrays-add-member-looking-for-elegant-code%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
why the single line of code requirement? [frown] a foreach loop is often far faster than anything that uses the pipeline.
– Lee_Dailey
Nov 12 '18 at 21:33
Saving code length to add clarity for further maintenance (on this example, in real life, where I have no performance issues, I save overall 1 full page of code)
– Philippe
Nov 12 '18 at 23:01
thanks for the rationale. [grin] it's wrong, but that is OK. take a look at the code posted by mklement0 for a thorough refutation of "too long". as for maintainability ... laying the steps out clearly is FAR more maintainable than a more-than-simple pipeline. ///// still, as my papa said "if we were all the same, the world would be boring as heck!" [grin]
– Lee_Dailey
Nov 12 '18 at 23:48