What is difference between {iterate} and {foreach} in smarty tpl files?
are they different in using 'from' phrase?
As far as I know, there is no command called "iterate" in Smarty. There is, however, a command called {section} that is often confused with {foreach}.
From the documentation at Smarty.net:
The {foreach} loop can do everything a {section} loop can do, and has
a simpler and easier syntax. It is usually preferred over the
{section} loop.
Also:
{section} loops cannot loop over associative arrays, they must be
numerically indexed, and sequential (0,1,2,...). For associative
arrays, use the {foreach} loop.
Hopefully that helps.
Related
I'm trying to program a numerical method in my ti-89, in TI-Basic language, the problem is that when I overwrite the variable inside the loop it doesn't do it, I'm new to this language and I don't know if I'm omitting some detail behind
Item()
prgm
Input "f(x)",a //call the function in text mode
define s(z,t) = a //convert the text into a function
local xa,ya //declare local variables
x->xa //assign values that I already have saved to local variables
y->ya
local i
For i,1,10
s(xa,ya)->xa //evaluate the function, and I have to rewrite the first parameter
EndFor
EndPrgm
I'm not entirely sure what's causing the problem, but I would try using a list to store the data instead if that is all there is. You can rewrite the list and clear it easily. You can store strings in these lists as well. Lists can be edited at all times, which will fix your problem. Although this solution might not be as efficient, it should work. I don't have my calculator with me so I can't test it, sorry :(. These two functions below add things to the list and clear the list.
L1(x,y,z)
ClrList L1
Good luck! TI-Basic can be difficult sometimes
I have this parameter as an array. The array is big, 100 cells. It is a parameter that can be initiated in omnet.ini file. The cells with even numbers should get value A and odd numbers should get value B. How can I do this in an automated manner?
Is there a way besides having all odd and even indices initiated one by one manually?
Wildcards can be useful but I do not know how to use them to separate odd and even indices.
Thanks.
You can access the actual module index with the index operator. Combining this with the conditional operator ?: you can easily define the value:
**.myModule[*].myParameter = index % 2 == 0 ? "A" : "B"
I'm not aware of any feature like this. There are a number of work-arounds you could use:
Provide two parameters and select the correct one in code
Use the volatile keyword (probably not appropriate here)
Put the entire thing in your .ini file
I'd personally implement the first approach, that way you can use the wildcard to pass both parameters ([*].myNode.parameterEven and [*].myNode.parameterUneven) and then set the correct values in your array in a for loop.
However, you could also use the volatile keyword in your NED file, see the manual for more details. However, this approach mostly works well if you have different parameters depending on which node you are assigning it to. For this case I think the first approach is better.
The last alternative is just putting the entire thing in your .ini file, which may be useful if you want to parameterize the array later.
This question already has answers here:
Multidimensional associative arrays in Bash
(2 answers)
Closed 2 years ago.
Can one construct an associative array whose elements contain arrays in bash? For instance, suppose one has the following arrays:
a=(a aa)
b=(b bb bbb)
c=(c cc ccc cccc)
Can one create an associate array to access these variables? For instance,
declare -A letters
letters[a]=$a
letters[b]=$b
letters[c]=$c
and then access individual elements by a command such as
letter=${letters[a]}
echo ${letter[1]}
This mock syntax for creating and accessing elements of the associate array does not work. Do valid expressions accomplishing the same goals exist?
This is the best non-hacky way to do it but you're only limited to accessing single elements. Using indirect variable expansion references is another but you'd still have to store every element set on an array. If you want to have some form of like anonymous arrays, you'd need to have a random parameter name generator. If you don't use a random name for an array, then there's no sense referencing it on associative array. And of course I wouldn't like using external tools to generate random anonymous variable names. It would be funny whoever does it.
#!/bin/bash
a=(a aa)
b=(b bb bbb)
c=(c cc ccc cccc)
declare -A letters
function store_array {
local var=$1 base_key=$2 values=("${#:3}")
for i in "${!values[#]}"; do
eval "$1[\$base_key|$i]=\${values[i]}"
done
}
store_array letters a "${a[#]}"
store_array letters b "${b[#]}"
store_array letters c "${c[#]}"
echo "${letters[a|1]}"
I think the more straightforward answer is "No, bash arrays cannot be nested."
Anything that simulates nested arrays is actually just creating fancy mapping functions for the keyspace of the (single layered) arrays.
Not that that's bad: it may be exactly what you want, but especially when you don't control the keys into your array, doing it properly becomes harder.
Although I like the solution given by #konsolebox of using a delimiter, it ultimately falls over if your keyspace includes keys like "p|q".
It does have a nice benefit in that you can operate transparently on your keys, as in array[abc|def] to look up the key def in array[abc], which is very clear and readable.
Because it relies on the delimiter not appearing in the keys, this is only a good approach when you know what the keyspace looks like now and in all future uses of the code. This is only a safe assumption when you have strict control over the data.
If you need any kind of robustness, I would recommend concatenating hashes of your array keys. This is a simple technique that is extremely likely to eliminate conflicts, although they are possible if you are operating on extremely carefully crafted data.
To borrow a bit from how Git handles hashes, let's take the first 8 characters of the sha512sums of keys as our hashed keys.
If you feel nervous about this, you can always use the whole sha512sum, since there are no known collisions for sha512.
Using the whole checksum makes sure that you are safe, but it is a little bit more burdensome.
So, if I want the semantics of storing an element in array[abc][def] what I should do is store the value in array["$(keyhash "abc")$(keyhash "def")"] where keyhash looks like this:
function keyhash () {
echo "$1" | sha512sum | cut -c-8
}
You can then pull out the elements of the associative array using the same keyhash function.
Funnily, there's a memoized version of keyhash you can write which uses an array to store the hashes, preventing extra calls to sha512sum, but it gets expensive in terms of memory if the script takes many keys:
declare -A keyhash_array
function keyhash () {
if [ "${keyhash_array["$1"]}" == "" ];
then
keyhash_array["$1"]="$(echo "$1" | sha512sum | cut -c-8)"
fi
echo "${keyhash_array["$1"]}"
}
A length inspection on a given key tells me how many layers deep it looks into the array, since that's just len/8, and I can see the subkeys for a "nested array" by listing keys and trimming those that have the correct prefix.
So if I want all of the keys in array[abc], what I should really do is this:
for key in "${!array[#]}"
do
if [[ "$key" == "$(keyhash "abc")"* ]];
then
# do stuff with "$key" since it's a key directly into the array
:
fi
done
Interestingly, this also means that first level keys are valid and can contain values. So, array["$(keyhash "abc")"] is completely valid, which means this "nested array" construction can have some interesting semantics.
In one form or another, any solution for nested arrays in Bash is pulling this exact same trick: produce a (hopefully injective) mapping function f(key,subkey) which produces strings that they can be used as array keys.
This can always be applied further as f(f(key,subkey),subsubkey) or, in the case of the keyhash function above, I prefer to define f(key) and apply to subkeys as concat(f(key),f(subkey)) and concat(f(key),f(subkey),f(subsubkey)).
In combination with memoization for f, this is a lot more efficient.
In the case of the delimiter solution, nested applications of f are necessary, of course.
With that known, the best solution that I know of is to take a short hash of the key and subkey values.
I recognize that there's a general dislike for answers of the type "You're doing it wrong, use this other tool!" but associative arrays in bash are messy on numerous levels, and run you into trouble when you try to port code to a platform that (for some silly reason or another) doesn't have bash on it, or has an ancient (pre-4.x) version.
If you are willing to look into another language for your scripting needs, I'd recommend picking up some awk.
It provides the simplicity of shell scripting with the flexibility that comes with more feature rich languages.
There are a few reasons I think this is a good idea:
GNU awk (the most prevalent variant) has fully fledged associative arrays which can nest properly, with the intuitive syntax of array[key][subkey]
You can embed awk in shell scripts, so you still get the tools of the shell when you really need them
awk is stupidly simple at times, which puts it in stark contrast with other shell replacement languages like Perl and Python
That's not to say that awk is without its failings. It can be hard to understand when you're first learning it because it's heavily oriented towards stream processing (a lot like sed), but it's a great tool for a lot of tasks that are just barely outside of the scope of the shell.
Note that above I said that "GNU awk" (gawk) has multidimensional arrays. Other awks actually do the trick of separating keys with a well-defined separator, SUBSEP. You can do this yourself, as with the array[a|b] solution in bash, but nawk has this feature builtin if you do array[key,subkey]. It's still a bit more fluid and clear than bash's array syntax.
For those stumbling on this question when looking for ways to pass command line arguments within a command line argument, an encoding such as JSON could turn useful, as long as the consumer agrees to use the encoding.
# Usage: $0 --toolargs '["arg 1", "arg 2"]' --otheropt
toolargs="$2"
v=()
while read -r line; do v+=("${line}"); done < <(jq -r '.[]' <<< "${toolargs}")
sometool "${v[#]}"
nestenc='{"a": ["a", "aa "],
"b": ["b", "bb", "b bb"],
"c d": ["c", "cc ", " ccc", "cc cc"]
}'
index="c d"
letter=()
while read -r line; do
letter+=("${line}")
done < <(jq -r ".\"${index}\"[]" <<< "${nestenc}")
for c in "${letter[#]}" ; do echo "<<${c}>>" ; done
The output follows.
<<c>>
<<cc>>
<<ccc>>
<<cc cc>>
I have issue with technically deep question about loops in ruby.
I have algorithm that is executed sequentially for array of Boolean values and operate on one data structures.
def function(boolean, data_structure)
The key point is that the order of execution is most important thing because expression
function(true, data_structure);function(true, data_structure); function(false, data_structure)
will leave other result in data structure than expression
function(true, data_structure);function(false, data_structure); function(true, data_structure)
I spent some time trying with each loop, but I didn't get any problems as other result in data structure due execution similar expression as follow
[true, true, false ....].each do |value| function(value, data_structure) end
My question: in default ruby configuration is my each loop is the same like followed for loop?
for i in 0..array.size do function(array[i], data_structure) end
Because each loop makes the code much clearer and easier to modify and I was thinking about leave each expression rather than using for loop.
(Of course in my case I have a lot more code rather than calling only function()..)
Yes, it's identical. It will loop through the elements of the array, in order.
I have a 4-dimensional NArray, and I'm overriding #each so that it only iterates over a single dimension, then using include Enumerable for functionality like #reject, #inject, etc. However, #sort still iterates over every individual element rather than over the dimension I've selected.
Is there a way to explicitly use Enumerable's #sort method, or do I have to write my own? I only have to call it once (so far), so it can be kind of weird or inconvenient.
NOTE: I realize that this question may seem like a duplicate. However, I do not want to ALWAYS override #sort, but rather just explicitly call Enumerable's #sort method.
If you call sort on the first level, whose elements are arrays, then sort will compare arrays. In order to compare arrays, the evaluation has to go inside those arrays, which means that it will be iterating over every level of array. It does not make sense to compare array elements while avoiding iterations into the sublevel. So if this is what you are trying to do, then there is no way.
NArray has already #sort method and existing methods are not overridden through include. In Ruby 2.0, you can use prepend instead of include.