Ассоциативные массивы в Сценариях оболочки

С помощью FlexBox

С помощью display: flex; вы можете указать свойства justify-content и align-items - center, чтобы центрировать дочерние элементы как по горизонтали, так и по вертикали.

Когда элемент display: flex представляет собой строку (flex-direction: row;), justify-content будет обрабатывать горизонтальное позиционирование, тогда как align-items обрабатывает вертикальное позиционирование. Когда flex-direction установлено в column, значения justify-content и align-items меняются местами.

Пример:

.parent-element {
  display: flex;
  /* flex-direction defaults to row */

  justify-content: center;
  align-items: center;
}

С помощью CSS Grid

Вы можете использовать свойство place-items для центрирования дочерних элементов сетки. Однако вы должны знать, что place-items в настоящее время поддерживается не всеми браузерами.

Пример:

.parent-element {
  display: grid;
  place-items: center;
}

Автоматическое заполнение поля

Иногда вы можете использовать значение auto для свойства margin, чтобы подтолкнуть элемент к центру.

Обязательно ознакомьтесь с этой записью, в которой объясняется , что необходимо для работы margin: auto; . ​​

Пример:

.child-element {
  /* top right bottom left -- all set to auto */
  margin: auto;
}

Абсолютное позиционирование с преобразованием

Вы можете расположить элемент в центре экрана, установив для свойства position значение absolute (это будет вытащите его из обычного документооборота). Затем вы можете использовать свойства left и top для перемещения элемента вниз и вправо 50%.

После того, как он выдвинут 50%, нам нужно переместить его обратно на половину ширины / высоты элемента, мы можем сделать это с помощью translate внутри свойства transform.

Пример:

.child-element {
  position: absolute;
  top: 50%;
  left: 50%;

  /* translate(, ) */
  transform: translate(-50%, -50%);
}

Отказ от ответственности:

Это не рекомендуется для элементов, которые являются частью вашего обычного потока документов, поскольку они, скорее всего, будут перекрывать другие элементы. Это отлично подходит для модальных тем не менее.

112
задан Reinstate Monica 29 September 2009 в 19:19
поделиться

7 ответов

Для добавления к ответу Irfan вот, более короткая и более быстрая версия get() так как это не требует никакого повторения по содержанию карты:

get() {
    mapName=$1; key=$2

    map=${!mapName}
    value="$(echo $map |sed -e "s/.*--${key}=\([^ ]*\).*/\1/" -e 's/:SP:/ /g' )"
}
20
ответ дан Community 24 November 2019 в 02:46
поделиться

Теперь ответ на этот вопрос.

Следующие сценарии моделируют ассоциативные массивы в сценариях оболочки. Его простое и очень легкое для понимания.

Карта является только никогда конечной строкой, которая имеет keyValuePair, сохраненный как - name=Irfan - designation=SSE - company=My:SP:Own:SP:Company

пробелы заменяются ':SP': для значений

put() {
    if [ "$#" != 3 ]; then exit 1; fi
    mapName=$1; key=$2; value=`echo $3 | sed -e "s/ /:SP:/g"`
    eval map="\"\$$mapName\""
    map="`echo "$map" | sed -e "s/--$key=[^ ]*//g"` --$key=$value"
    eval $mapName="\"$map\""
}

get() {
    mapName=$1; key=$2; valueFound="false"

    eval map=\$$mapName

    for keyValuePair in ${map};
    do
        case "$keyValuePair" in
            --$key=*) value=`echo "$keyValuePair" | sed -e 's/^[^=]*=//'`
                      valueFound="true"
        esac
        if [ "$valueFound" == "true" ]; then break; fi
    done
    value=`echo $value | sed -e "s/:SP:/ /g"`
}

put "newMap" "name" "Irfan Zulfiqar"
put "newMap" "designation" "SSE"
put "newMap" "company" "My Own Company"

get "newMap" "company"
echo $value

get "newMap" "name"
echo $value

править: Просто добавленный другой метод для выборки всех ключей.

getKeySet() {
    if [ "$#" != 1 ]; 
    then 
        exit 1; 
    fi

    mapName=$1; 

    eval map="\"\$$mapName\""

    keySet=`
           echo $map | 
           sed -e "s/=[^ ]*//g" -e "s/\([ ]*\)--/\1/g"
          `
}
4
ответ дан Irfan Zulfiqar 24 November 2019 в 02:46
поделиться

Я думаю, что необходимо отступить и думать о том, какова карта или ассоциативный массив, действительно. Все, что это, является способом сохранить значение для данного ключа и вернуть то значение быстро и эффективно. Можно также хотеть смочь выполнить итерации по ключам для получения каждой пары значения ключа, или клавиш Delete и их присваиваемых значений.

Теперь, думайте о структуре данных, которую Вы используете все время в сценариях оболочки, и даже только в оболочке, не пишущий сценарий, который имеет эти свойства. Озадаченный? Это - файловая система.

Действительно, все, у Вас должен быть ассоциативный массив в программировании оболочки, является временным каталогом. mktemp -d Ваш конструктор ассоциативного массива:

prefix=$(basename -- "$0")
map=$(mktemp -dt ${prefix})
echo >${map}/key somevalue
value=$(cat ${map}/key)

Если Вы не испытываете желание использовать echo и cat, можно всегда писать некоторые небольшие обертки; эти смоделированы прочь Irfan, хотя они просто производят значение вместо того, чтобы установить произвольные переменные как $value:

#!/bin/sh

prefix=$(basename -- "$0")
mapdir=$(mktemp -dt ${prefix})
trap 'rm -r ${mapdir}' EXIT

put() {
  [ "$#" != 3 ] && exit 1
  mapname=$1; key=$2; value=$3
  [ -d "${mapdir}/${mapname}" ] || mkdir "${mapdir}/${mapname}"
  echo $value >"${mapdir}/${mapname}/${key}"
}

get() {
  [ "$#" != 2 ] && exit 1
  mapname=$1; key=$2
  cat "${mapdir}/${mapname}/${key}"
}

put "newMap" "name" "Irfan Zulfiqar"
put "newMap" "designation" "SSE"
put "newMap" "company" "My Own Company"

value=$(get "newMap" "company")
echo $value

value=$(get "newMap" "name")
echo $value

править: Этот подход на самом деле вполне немного быстрее, чем линейный поиск с помощью sed предложенный корреспондентом, а также более устойчивый (он позволяет ключам и значениям содержать - =, пространство, qnd ": SP":). То, что это использует файловую систему, не заставляет его замедлиться; эти файлы, как на самом деле никогда гарантируют, не будут записаны в диск, если Вы не будете звонить sync; для временных файлов как это с коротким временем жизни не маловероятно, что многие из них никогда не будут писаться в диск.

Я сделал несколько сравнительных тестов кода Irfan, модификации Jerry's кода Irfan и моего кода, с помощью следующей программы драйвера:

#!/bin/sh

mapimpl=$1
numkeys=$2
numvals=$3

. ./${mapimpl}.sh    #/ <- fix broken stack overflow syntax highlighting

for (( i = 0 ; $i < $numkeys ; i += 1 ))
do
    for (( j = 0 ; $j < $numvals ; j += 1 ))
    do
        put "newMap" "key$i" "value$j"
        get "newMap" "key$i"
    done
done

Результаты:

    $ time ./driver.sh irfan 10 5

    real    0m0.975s
    user    0m0.280s
    sys     0m0.691s

    $ time ./driver.sh brian 10 5

    real    0m0.226s
    user    0m0.057s
    sys     0m0.123s

    $ time ./driver.sh jerry 10 5

    real    0m0.706s
    user    0m0.228s
    sys     0m0.530s

    $ time ./driver.sh irfan 100 5

    real    0m10.633s
    user    0m4.366s
    sys     0m7.127s

    $ time ./driver.sh brian 100 5

    real    0m1.682s
    user    0m0.546s
    sys     0m1.082s

    $ time ./driver.sh jerry 100 5

    real    0m9.315s
    user    0m4.565s
    sys     0m5.446s

    $ time ./driver.sh irfan 10 500

    real    1m46.197s
    user    0m44.869s
    sys     1m12.282s

    $ time ./driver.sh brian 10 500

    real    0m16.003s
    user    0m5.135s
    sys     0m10.396s

    $ time ./driver.sh jerry 10 500

    real    1m24.414s
    user    0m39.696s
    sys     0m54.834s

    $ time ./driver.sh irfan 1000 5

    real    4m25.145s
    user    3m17.286s
    sys     1m21.490s

    $ time ./driver.sh brian 1000 5

    real    0m19.442s
    user    0m5.287s
    sys     0m10.751s

    $ time ./driver.sh jerry 1000 5

    real    5m29.136s
    user    4m48.926s
    sys     0m59.336s

32
ответ дан Brian Campbell 24 November 2019 в 02:46
поделиться

Другая опция, если мобильность не является Вашим основным беспокойством, состоит в том, чтобы использовать ассоциативные массивы, которые встроены к оболочке. Это должно работать в ударе 4.0 (доступный теперь на большинстве главных дистрибутивов, хотя не на OS X, если Вы не устанавливаете его сами), ksh, и zsh:

declare -A newmap
newmap[name]="Irfan Zulfiqar"
newmap[designation]=SSE
newmap[company]="My Own Company"

echo ${newmap[company]}
echo ${newmap[name]}

В зависимости от оболочки Вы, возможно, должны сделать a typeset -A newmap вместо declare -A newmap, или в некоторых это не может быть необходимо вообще.

143
ответ дан Brian Campbell 24 November 2019 в 02:46
поделиться
hput () {
  eval hash"$1"='$2'
}

hget () {
  eval echo '${hash'"$1"'#hash}'
}
hput France Paris
hput Netherlands Amsterdam
hput Spain Madrid
echo `hget France` and `hget Netherlands` and `hget Spain`

$ sh hash.sh
Paris and Amsterdam and Madrid
15
ответ дан 24 November 2019 в 02:46
поделиться

Как уже упоминалось, я обнаружил, что наиболее эффективный метод - это записать ключ / значение в файл, а затем использовать команду grep / awk для их получения. Это звучит как всевозможные ненужные операции ввода-вывода, но дисковый кеш срабатывает и делает его чрезвычайно эффективным - намного быстрее, чем пытаться сохранить их в памяти с помощью одного из вышеперечисленных методов (как показывают тесты).

Вот быстрый и чистый метод, который мне нравится:

hinit() {
    rm -f /tmp/hashmap.$1
}

hput() {
    echo "$2 $3" >> /tmp/hashmap.$1
}

hget() {
    grep "^$2 " /tmp/hashmap.$1 | awk '{ print $2 };'
}

hinit capitols
hput capitols France Paris
hput capitols Netherlands Amsterdam
hput capitols Spain Madrid

echo `hget capitols France` and `hget capitols Netherlands` and `hget capitols Spain`

Если вы хотите принудительно использовать одно значение для каждого ключа, вы также можете выполнить небольшое действие grep / sed в hput ().

0
ответ дан 24 November 2019 в 02:46
поделиться

Bash4 поддерживает это нативно. Не используйте grep или eval, это самые уродливые из хаков.

Многословный, подробный ответ с примерами кода см: https://stackoverflow.com/questions/3467959

7
ответ дан 24 November 2019 в 02:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: