Today is AdventOfCode Day18, I’m really happy that I finished it earlier than I expected, here’s my journey since 2015. Today’s question is another one with BFS of map traverse. So I’ll definitely write up something about Path finding by the end of the competition. For now, I want to mention a utility function, the array slice under Javascript. Javascript isn’t quite flexible when it comes to the parsing and manipulation comparing to other languages such as Python. So I have rely on some comparative ways.
If I want to slice the array to take a portion of it, there actually has a built-in function slice
for Javascript. Right out of the box, it’ll clone the original array.
[1,2,3].slice() // [1,2,3]
The result points to a new memory address, not the original array. This can be really useful if you want to chain the result with other functions. The real usage is when you provide some input to the slice.
Start Index
The slice can take up to two input parameters. The first one is called the start index, and this would tell where it should start the slice.
[1,2,3].slice(0) // [1,2,3]
[1,2,3].slice(1) // [2,3]
[1,2,3].slice(2) // [3]
[1,2,3].slice(3) // []
By default, it’ll slice till the end of the array. The interesting thing about the start index is that not only you can use a zero or a positive number, but also you can use a negative number.
[1,2,3].slice(-1) // [3]
[1,2,3].slice(-2) // [2,3]
[1,2,3].slice(-3) // [1,2,3]
When it’s a negative number, it refers to an index counting from the end n
. For instance, -1
refers to the last element of the array, -2
refers to the second last element, and etc. Notice there’s no -0
, because there’s no element beyond the last element. This can be quite apparent or confusing depending on the situation.
End index
The slice can take a second parameter called the end index.
[1,2,3].slice(0,3) // [1,2,3]
[1,2,3].slice(0,2) // [1,2]
[1,2,3].slice(0,1) // [1]
The end index, also referred as a range index, points to the element index + 1. What does it mean? To explain this, it would be relatively easier if we can relate to the for
statement:
for (let i = 0; i < n; i++) {}
The variable i
starts at 0
, the start index; and ends at n
, the end index. The end index isn’t the last element of the array, because that would be n - 1
. But when it comes to the end index, n
stands for the “end” with the the last element included. If it’s your first time using the end index, just remember how for
statement is written, or simply remember taking the last element index and then plus one to it. Another way to think of it is that the end index is open ended, [start, end)
.
As in the start index, the end index can be negative as well.
[1,2,3].slice(0,-1) // [1,2]
[1,2,3].slice(0,-2) // [1]
Pay a bit more attention here. -1
refers to the last element, therefore if used as the second parameter, it means the last element will be excluded, as we have explained, open ended.
Kool but what if I want to include the last element?
[1,2,3].slice(0) // [1,2,3]
Yes, simply use the single parameter input.
Usages
Ok. Why is everything I mentioned here useful? Because, as far as I know, this is the only function in Javascript that can be used to manually select a portion of an array without touching the original array.
processed = processed.slice(0, q);
const rest = sequence.slice(1);
res = dfs(sequence.slice(first + 1), groups.slice(1));
let key = scores.slice(-20).join(",");
label = seq.slice(0, -1);
const steps = parseInt(color.slice(2, 7), 16);
return str.slice(1, -1)
const s = seg.slice(0, k);
return [s[0], s[1], Number(s.slice(2)), seg.slice(k + 1)];
const name = str.slice(0, i);
obj[name] = str.slice(i + 1, -1)
return this.slice(0, n);
permute(array.slice(i + 1), length - 1)
Over the past 18 days, I have used the slice
more than 10 times. This is after I have created my own array utility file to handle array quicker. But when it comes to unique requirement, I still come to use the slice
. I Let’s take a look at the common usages.
The most common one is to simulate a take operation, such as getting the first few or last few elements, like slice(0, q)
, slice(1)
, slice(-20)
and etc. A quite useful usage is to exclude the last element when performing the take, like slice(i + 1, -1)
, slice(1, -1)
and etc. Because otherwise you’ll have to pop the element and touch the original array, which normally would have to take me at least two lines of code.
The second common usage is for the parsing. Imaging you have a string and you want to take some middle portion.
"(#70c710)".slice(3, 8) // "70c71"
We can slice it to get the portion 70c71
. It’s hard to use split
or match
in this case, because there’s no clear separator or pattern to guide us. When we are given the precise indexes, slicing seems to me the most straight-forward way to go.
Conclusion
Array slice is really handy, especially for the parsing purpose. Moreover, it won’t touch your original array, so rest assured you won’t end up with too many bugs using it.