Skip to content

Commit

Permalink
edits
Browse files Browse the repository at this point in the history
  • Loading branch information
glennj committed Feb 21, 2025
1 parent 22641c7 commit 221757c
Showing 1 changed file with 19 additions and 11 deletions.
30 changes: 19 additions & 11 deletions concepts/more-arrays/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This document will show more ways to use arrays.

In the previous Arrays chapter, you saw `"${myarray[@]}"`, with the `@` index, to expand the array into the individual elements.
But sometimes you want to join all the elements into a single string.
For this, use the `*` index:
For this, use the `*` index:

```bash
echo "${myarray[*]}"
Expand All @@ -18,12 +18,11 @@ You are required to enclose the expansion in double quotes.
Bash uses the _first character_ of the `IFS` builtin variable as the separator character.
By default, `$IFS` consists of space, tab and newline.

This demo shows that the `mystring` variable contains "one two three four".

```bash
myarray=(one two three four)
mystring="${myarray[*]}"
declare -p mystring
# => declare -- mystring="one two three four"
```

We can manipulate the `IFS` variable to use a different separator character:
Expand All @@ -33,13 +32,11 @@ myarray=(one two three four)
IFS=","
mystring="${myarray[*]}"
declare -p mystring
# => declare -- mystring="one,two,three,four"
```

Now, `mystring` contains "one,two,three,four".

~~~~exercism/advanced
We can encapsulate this into a function.
This will output "one:two:three:four".
```bash
join() {
Expand All @@ -50,11 +47,12 @@ join() {
}
join ":" "${myarray[@]}" # note, the "@" index
# => "one:two:three:four"
```
Using a local variable in a function means we don't have restore IFS back to it's previous value.
Localizing `IFS` in the function means we don't have to save the old value and restore it back to it's previous value in the global scope.
As a refinement, the special parameter `"$*"` has the same functionality here, so we don't need to save a copy of the function's arguments:
As a refinement, the special parameter `"$*"`, when quoted, has the same functionality so we don't need to save a copy of the function's arguments:
```bash
join() {
Expand All @@ -78,7 +76,11 @@ declare -p subarray # => subarray=([0]="one" [1]="two")

subarray=("${myarray[@]:1:3}")
declare -p subarray # => subarray=([0]="two" [1]="three" [2]="four")
```

Omitting the length part means "from the offset to the end of the array":

```bash
subarray=("${myarray[@]:2}")
declare -p subarray # => subarray=([0]="three" [1]="four")
```
Expand All @@ -90,7 +92,7 @@ There are 3 techniques to pass an array to a function, and only one of them allo

### Pass the Elements

You can just pass the array's values, and collect them in the function.
In the first technique, you just pass the array's values and collect them into a local array in the function.

```bash
myfunc() {
Expand All @@ -114,8 +116,8 @@ For these two techniques, you pass the array _name_ as a string.

Suppose you have variable `x=5` and variable `y=x`, and you want to use the `y` variable to get the value `5`.
Some other languages let you do `$$y` but not Bash.
Bash has a technique called "indirect expansion" (described in the manual in [Shell Parameter Expansion][parameter-expansion]).
In bash, this uses the `!` in a different way than we have seen before:
Bash has a technique called **indirect expansion** (described in the manual in [Shell Parameter Expansion][parameter-expansion]).
In bash, this uses the `!` character in a different way than we have seen before:

```bash
x=5
Expand All @@ -138,6 +140,7 @@ array_original=(11 22 33 44)
myfunc "array_original"
```

This technique is quite messy.
The `temp` variable will contain the _string `"array_original[@]"`.
Then the indirect expansion expands to the global array's values.

Expand Down Expand Up @@ -183,9 +186,12 @@ myfunc() {
local IFS=,
echo "${a[*]}"
}
# same name as the function's local variable
a=(one two three)
myfunc a
```
```none
bash: local: warning: a: circular name reference
bash: warning: a: circular name reference
Expand Down Expand Up @@ -216,5 +222,7 @@ for item in "$@"; do
done
```

If your goal is to write "portable" shell scripts, you'll use the positional parameters to store a "list" of values.

[arrays]: https://exercism.org/tracks/bash/concepts/arrays
[parameter-expansion]: https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion

0 comments on commit 221757c

Please sign in to comment.