I’m not really grokking how RouterOS handles Arrays, and the documentation in this respect seems rather lacking. (Or my code-fu is too weak to properly parse what’s there, just as likely)
If someone could provide a syntactically valid example of the above that would be much appreciated.
The big, and somewhat unintuitive for me, takeaway is that the key must be a string, even if you’re just using decimal numbers.
I don’t see an easy way to filter the results of a :foreach through the array, but since this is a fixed array with known size, I can loop through it myself easily enough.
Almost there, actually I can work around this, but it’s not perfect, so I’m going to throw it out there:
Compare this code
# Statically defined array, working properly
{
:local testArray {11=1; 12=1; 21=1; 22=1}
:local testRows 2
:local testCols 2
:local testRowSize 10
:put $testArray
:for x from=1 to=$testRows step=1 do={
:for y from=1 to=$testCols step=1 do={
:local value ($testArray->[:tostr (($testRowSize * $x) + $y)])
:put ("Type of row $x column $y is $[:typeof $value] with value $value")
}
}
}
Which outputs this:
11=1;12=1;21=1;22=1
Type of row 1 column 1 is num with value 1
Type of row 1 column 2 is num with value 1
Type of row 2 column 1 is num with value 1
Type of row 2 column 2 is num with value 1
To this code which builds the array dynamically
# Dynamically defined array based on the above static array
{
:local testRows 2
:local testCols 2
:local testRowSize 10
:local testArray
:for x from=1 to=$testRows step=1 do={
:for y from=1 to=$testCols step=1 do={
# :put $testArray
:local coord (($testRowSize * $x) + $y)
:if (($x = 1) and ($y = 1)) do={ \
:set testArray {11=1}
} else={ \
:set ($testArray->[:tostr $coord]) 1
}
}
}
:put $testArray
:for x from=1 to=$testRows step=1 do={
:for y from=1 to=$testCols step=1 do={
:local value ($testArray->[:tostr (($testRowSize * $x) + $y)])
:put ("Type of row $x column $y is $[:typeof $value] with value $value")
}
}
}
And outputs this:
11=1;12=1;21=1;22=1
Type of row 1 column 1 is num with value 1
Type of row 1 column 2 is num with value 1
Type of row 2 column 1 is num with value 1
Type of row 2 column 2 is num with value 1
I’ve got to use an ugly kludge to start the array, since RouterOS won’t let me use variables in a :set statement for an array
:global UserDatabase [:toarray ""];
# The key for the array is the username of the user.
# The structure of every user record is as follows:
# password | email | tel | last IP | something | something else |
:set ($UserDatabase->"username1") {"supersecret";"username1@example.com";"+123456789";"0.0.0.0";0;0};
:set ($UserDatabase->"username2") {"megasecret";"username2@example.com";"+987654321";"0.0.0.0";0;0};
# Printing specific property (column) of the data for specific user:
:put ($UserDatabase->"username1"->0);
know I want to:
find the index of the array username2
extract this the username2-array from UserDatabase-array by index
currently, I could your approach to check if the username2-array exists. If so, called it by its name (named array).
And about index… the name itself is the index, a numeric value do not exist…
:foreach index,content in=$UserDatabase do={:put $index; :put $content}
username1
supersecret;username1@example.com;+123456789;0.0.0.0;0;0
username2
megasecret;username2@example.com;+987654321;0.0.0.0;0;0
username3
megasecret;username3@example.com;+987654321;0.0.0.0;0;0
username4
megasecret;username4@example.com;+987654321;0.0.0.0;0;0
username5
megasecret;username5@example.com;+987654321;0.0.0.0;0;0
username9
megasecret;username9@example.com;+987654321;0.0.0.0;0;0
For search inside the array (on username’s part)
:global searcthis “username1”
:put [:typeof ($UserDatabase->$searcthis)]
array
:global searcthis “username30”
:put [:typeof ($UserDatabase->$searcthis)]
nothing
if nothing the index do not exist
If array (or any other variable types stored inside the array filed) the index exist (empty or not)