Skip to content

Commit 3810cd3

Browse files
committed
main
1 parent 5f70229 commit 3810cd3

File tree

7 files changed

+207
-19
lines changed

7 files changed

+207
-19
lines changed

docs/document/Powershell/docs/1.Overview.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,3 @@
88
- All language syntax, pattern syntax and even strings are case-insensitive. (There's exception for file system on non-Windows platform)
99
- Everything is object, more than plain text in shell.
1010
- Powershell formats the object value as a table if the object is not a primitive type. For primitive types, `Tostring()` will be used instead.
11-
- Always handle both array and singular object.
12-
- A powershell cmdlet always accepts an array or an single object as input parameter. And returns the result as an array or an object too.

docs/document/Powershell/docs/Language/Array.md

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ $foo = @() # empty array
1515

1616
> [!NOTE]
1717
> The default type of a array literal is `object[]`, you can annotate with a type.
18+
> To create an empty array with fixed size, invoke `new()` constructor, this is also strongly typed.
1819
> ```ps1
1920
> [int[]]$foo = 1, 2, 3
21+
> $bar = [int[]]::new(5)
2022
> ```
2123
2224
> [!TIP]
@@ -28,17 +30,19 @@ $foo = @() # empty array
2830
>```ps1
2931
>(1,2,3).Length # 3
3032
>
33+
>$(1,2,3).Length # 3 this has different semantic but with same result
34+
>
3135
>(,(1,2,3)).Length # 3 # does spread items # [!code highlight]
3236
>
3337
>(,@(1,2,3)).Length # 1 # does not spread items # [!code highlight]
3438
>
3539
>((gci), (gci ..)).Length # 2 # [!code highlight]
3640
> ```
3741
38-
### Collect from Expressions
42+
### From Expression and Statement
3943
40-
`@()` actually collects from expressions, and all items from expressions will be flattened into a whole array.
41-
So it can be another way to spread out arrays into one.
44+
`@()` collects from expressions or statements like control flows that implicitly returns.
45+
You can choose either flatten items from expressions or treat them as a sub-array.
4246
4347
- Use `;` to separate expressions for flatten arrays from them.
4448
- Use `,` to separate expressions if you want them to be sub-array.
@@ -49,25 +53,54 @@ So it can be another way to spread out arrays into one.
4953
5054
@((ls), (ls ..)).Length # 2
5155
@(ls; ls ..).Length # > 0
56+
57+
@(
58+
if ($true) {
59+
'yield this value to the array'
60+
'yield this value again'
61+
}
62+
).Length # 2
5263
```
5364
54-
## Access an Item
65+
### From Enumerator
5566

56-
Powershell allows indexer syntax to access one or more items at a time.
67+
Similar to expression, you can collect items from a `IEnumerator`.
68+
69+
```ps1
70+
$foo = @{
71+
Name = 'foo'
72+
Age = 18
73+
}
74+
75+
@($foo.GetEnumerator()).Length # 2, System.Collections.DictionaryEntry from the HashTable # [!code highlight]
76+
```
77+
78+
## Access Item
79+
80+
Powershell allows indexer syntax to access one or more items at a time or use `Select-Object`.
5781

5882
```ps1
5983
@(1,2,3)[0] # 1
60-
@(1,2,3)[0, 2] # 1, 3
84+
@(1,2,3) | select -index 1 # 2
85+
@(1,2,3)[0, 1] # 1, 2 returns an array though
6186
```
6287

88+
> [!NOTE]
89+
> The default value of a array item is `$null`.
90+
> Since it's a dynamic language, there's no error raised when index is out of the range.
91+
6392
## Concatenation
6493

65-
Generates new array from two concatenated.
94+
Generates new array from two concatenated or with new item.
6695

6796
```ps1
6897
((1,2,3) + (1,2,3)).Length # 6
98+
(1,2,3) + 4 # 1,2,3,4
6999
```
70100

101+
> [!NOTE]
102+
> Can use `+=` when you operate on a array variable.
103+
71104
## Repetition
72105

73106
Use `*` to repeat the array content for certain times.
@@ -76,6 +109,12 @@ Use `*` to repeat the array content for certain times.
76109
((1,2,3) * 3).Length # 9
77110
```
78111

112+
A pratical usage of repetition is initialization with same value to the whole array.
113+
114+
```ps1
115+
@(255) * 100 # Fill up array sized 100 with 255 to all elements
116+
```
117+
79118
## Slicing
80119

81120
Use range operator to slice an array.
@@ -107,6 +146,54 @@ Separate different ranges by `+` to generate a range union.
107146
(1..10)[0..2+4..5+7]
108147
```
109148

149+
## Substration
150+
151+
To substract a collection from another collection, you can certainly use `LINQ` or use a simple pipeline.
152+
153+
```ps1
154+
@(1,2,3) | where { @(1, 2) -notcontains $_ } # 3
155+
```
156+
157+
## Null Checking
158+
159+
Checking null for collections is a quirk in PowerShell, `$arr -eq $null` checks all items instead of the whole array.
160+
161+
```ps1
162+
$arr = 1,2,3
163+
164+
$arr -eq $null # empty array
165+
166+
$null -eq $arr # False, the result we expected # [!code highlight]
167+
168+
if ($arr) { 'array is not null and not empty' } # check both empty and null
169+
```
170+
171+
## To List
172+
173+
PowerShell allows direct casting a array to an `ArrayList` or generic `List<T>`.
174+
175+
```ps1
176+
using namespace System.Collections.Generic
177+
178+
[List[int]]@(1,2,3)
179+
180+
[System.Collections.ArrayList]@(1,2,3)
181+
```
182+
183+
## Filtering & Transformation by Keyword Operators
184+
185+
Keyword operators has special functionalities on collections.
186+
`-match`, `-notmatch`, `-replace`, `-split` handles for all items in the left operand collection, the result is always an array.
187+
188+
```ps1
189+
# Returns items that matches the regex
190+
@('John', 'Jane', 'Janet') -match 'Jane' # Jane, Janet.
191+
(@('John', 'Jane', 'Janet') -notmatch 'Jane') -is [array] # True, only John matches and still an array.
192+
193+
@('John', 'Jane', 'Janet') -replace 'J','K' # Kohn Kane Kanet
194+
'1,2,3','1,2,3' -split ',' # 1 2 3 1 2 3, strings
195+
```
196+
110197
## Multi-Dim Array
111198

112199
You'll have to create Multi-Dim array from .NET type constructor only.

docs/document/Powershell/docs/Language/HashTable.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,66 @@
11
# HashTable
22

3+
HashTable is a dynamicly typed data structure in PowerShell, it implements `IDictionary` but is wrapped with the extended types system.
4+
It's the native type and is unique to PowerShell itself.
5+
6+
```ps1
7+
@{} -is [System.Collections.IDictionary] # True
8+
```
9+
10+
## Creation
11+
12+
PowerShell has builtin syntax for creating a HashTable.
13+
Inline declaration requires `;` to distinguish key-value pairs.
14+
15+
```ps1
16+
$foo = @{
17+
Name = 'foo'
18+
Age = 18
19+
}
20+
$foo = @{ Name = 'foo'; Age = 18 }
21+
```
22+
23+
### Ordered HashTable
24+
25+
`[ordered]` is a mark can be used when creating HashTable literal, it makes sure that all entries are ordered as in declaration and subsequent appending.
26+
27+
```ps1
28+
([ordered]@{
29+
C = 'C'
30+
B = 'B'
31+
A = 'A'
32+
}).Keys # C B A
33+
34+
@{
35+
C = 'C'
36+
B = 'B'
37+
A = 'A'
38+
}.Keys # B C A
39+
```
40+
41+
> [!NOTE]
42+
> `[ordered]` can not be used as type, but it's indeed a `System.Collections.Specialized.OrderedDictionary`.
43+
>```ps1
44+
>([ordered]@{}).GetType().FullName # System.Collections.Specialized.OrderedDictionary
45+
>```
46+
47+
## Access Values
48+
49+
You can access value of one or more keys by indexer.
50+
```ps1
51+
$foo['Name'] # foo
52+
$foo['Name', 'Age'] # @('foo', 18)
53+
```
54+
55+
`.` accessor would also works **as long as there's no duplicated Extended Property with the same name of the key you passed.**
56+
57+
```ps1
58+
$foo.Name # foo
59+
```
60+
61+
> [!TIP]
62+
> Always use indexer to access value of a HashTable. `.` will prefer Extended Property that might be unexpected.
63+
364
## Merging
465

566
```ps1

docs/document/Powershell/docs/Language/String.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,40 @@ Use double `'` to escape `'` in a verbatim string.
9191
> [!NOTE]
9292
> See [about_Specical_Characters](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters?view=powershell-7.4)
9393
94+
## Arithmetic with Numerics
95+
96+
Powershell will try to convert the string on the right operand to the same type as left operand.
97+
Exception will be raised if conversion failed.
98+
99+
```ps1
100+
1 + '2' # 3
101+
'2' + 1 # '21'
102+
[DateTime]::Now + '00:00:15:00' # adds 15 minutes
103+
```
104+
94105
## Split & Join
95106

107+
```ps1
108+
'1,2,3' -split ',' # 1 2 3 as strings
109+
(gci -file) -join ',' # ToString is invoked to evaluated objects to string.
110+
```
111+
112+
## Match & Replace
113+
114+
```ps1
115+
'Janet is a girl' -match 'Jane' # True
116+
'Janet is a girl' -replace '^Janet', 'Jane'
117+
```
118+
96119
## Format String
97120

121+
Template string syntax is the same as `C#`.
122+
Standard numeric format like `:C`, `:X` are supported.
123+
124+
```ps1
125+
'This is a {0} string' -f 'format'
126+
```
127+
98128
## Repetition
99129

100130
Use `*` to repeat a string.

docs/document/Powershell/docs/Object Manipulation/Object Members.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ The whole array returned from `Get-Member` is `object[]`, each item inside is a
2828
### Inspect from Object
2929

3030
To treat a whole collection as the object to be inspected, do not pipe it, pass it to `-InputObject` instead.
31+
Or magically wrap it as a single-item collection.
3132

3233
```ps1
3334
gm -InputObject (gci -file) # TypeName: System.Object[]
35+
,(gci -file) | gm
3436
```
3537

3638
## Member Types
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Overview
2+
3+
- Intrinsic Members

docs/document/Powershell/docs/Understanding Pipeline.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Overview of pipeline in powershell:
1010

1111

1212

13-
## How Cmdlet Accept Pipeline Input
13+
## Pipeline Input Strategy
1414

1515
There's two solution when a pipeline input comes in as a fallback:
1616

@@ -33,7 +33,7 @@ gci -File | spps
3333
ByValue is always tried first, and then use ByPropertyName, or it finally throws.
3434
A parameter accepts pipeline input does not necessarily have both solutions, it can have at least one of them.
3535

36-
## How PowerShell Enumerate Pipeline Input
36+
## Pipeline Input as Enumerator
3737

3838
As we know, PowerShell can handle multiple objects from an enumerator from object that implements `IEnumerable` or `IEnumerable<T>`, or even duck typed with `GetEnumerator`.
3939

@@ -43,28 +43,33 @@ While for types that are not linear collection, manually invoking `GetEnumerator
4343
- HashTable has dynamic typing so we can't presume a uniformed calculation for our cmdlet
4444
- `string` is `IEnumerable` but we surely don't expect the auto enumeration.
4545

46+
This is simply because these types are more likely to be treated as a whole object, even when dictionaries are `IEnumerable<KeyValuePair<,>>`.
47+
4648
```ps1
4749
$table = @{ Name = 'foo'; Age = 18 }
4850
($table | measure).Count # 1
4951
($table.GetEnumerator() | measure).Count # 2 # [!code highlight]
5052
```
5153

52-
This is simply because these types are more likely to be treated as a whole object, even when dictionaries are `IEnumerable<KeyValuePair<,>>`.
53-
54-
5554
## Enumerate Pipeline Items
5655

57-
You can use `$input` to refer to the enumerator passed to the function. This is another way to access pipeline input items but with more control.
56+
You can use `$input` to refer to the enumerator passed to the function. This is one way to access pipeline input items but with more control.
5857
Another option is use `$_` to represent the current item in `process` block, this is way more limited but commonly used.
5958

59+
> [!NOTE]
60+
> `$_` and `$input` are isolated, they don't affects each other.
61+
6062
- `$input` represents a enumerator for pipeline input in `process` block.
6163
- `$input` represents the whole collection for pipeline input in `end` block.
6264
- `$input` will be consumed after being used once in either `process` or `end`. Use `Reset` to get it back.
6365
- You can't use `$input` in both `process` and `end`.
6466

6567
### Access Current Item
6668

67-
`$input.Current` have to manually invoke `MoveNext` before you access `Current` in `process` block since it's not a `while` loop.
69+
> We're not going to talk about `$_`, it's fairly simple. All the quirks is about `$input`.
70+
71+
`$input.Current` is `$null` by default, you'll have to manually invoke `MoveNext` before you access `Current` in `process` block since it's not a `while` loop.
72+
6873

6974
```ps1
7075
function Test {
@@ -122,7 +127,7 @@ gci -file | Test
122127
If you write a custom function that have one or more parameters accept pipeline input, what is going on inside?
123128

124129
- In `begin` block, there's no value assigned to each `ByPropertyName` parameter, they remain default.
125-
- In `process` block, each
130+
- In `process` block, each `ByPropertyName` parameter represents the current property value extracted from the current pipeline input object.
126131

127132
```ps1
128133
function Foo {
@@ -139,11 +144,13 @@ function Foo {
139144
}
140145
141146
process {
142-
$Name
143-
$Length
147+
$Name # Name of current pipeline item
148+
$Length # Length of current pipeline item
144149
}
145150
}
146151
147152
gci -file | Foo
148153
```
149154

155+
> [!TIP]
156+
> `ByPropertyName` parameter can also be a array type, it all depends the implementation you want, it behaves the same.

0 commit comments

Comments
 (0)