Para anteponer elementos a una matriz, simplemente puede hacer:
a[1,0]=(more elements)
O puedes hacer:
a=(more elements "$a[@]")
Tenga en cuenta que haciendo:
a=(more elements $a)
eliminaría los elementos vacíos en $a
.
Ahora, para hacer una función para eso, para eso es eval
, pero tienes que tener la sintaxis correcta:
prepend() {
eval "${1}[1,0]"='("${@[2,-1]}")'
}
Vea cómo el ("${@[2,-1]}")
se cita solo -, por lo que se pasa literalmente a eval
.
O de la forma más larga, pero no funcionaría paraprepend var more elements
(cuando el nombre de la variable esvar
):
prepend() {
local var=$1; shift
eval "$var"='("$@" "${'"$var"'[@]}")'
}
El código que desea eval
evaluar sobre prepend varname...
es:
varname=("$@" "${varname[@]")
No desea que "$@"
se expanda antes de pasar a eval
. Solo $var
necesita expandirse allí.
Tenga en cuenta que el indicador de expansión variable P
es tan peligroso como eval
cuando se usa con datos sin desinfectar.
var='x[$(uname>&2)0]'
echo "${(P)var}"
Ejecutará ese comando uname
.
Ваша функция prepend
может быть написана без eval
, если вы зацикливаете элементы, чтобы сдвинуть их по одному.
$ prepend () {
then> local i=$#*
then> while [[ $i > 1 ]]; do
then> typeset -g "${1}[1,0]=$*[$i]"
then> i=$((i - 1))
then> done
then> }
$ foo=(a 'b c' d)
$ prepend foo m 'n o p' q r
$ print -l $foo
m
n o p
q
r
a
b c
d
$
Обратите внимание, что -g
необходимо для того, чтобы набор принял установку не -локального элемента массива, но это не означает, что массив, на который ссылается $1
, не может быть локальным для вызывающей функции. Это просто означает, что «можно просмотреть стек вызовов функций, чтобы найти этот массив».