Проверить, существует ли значение в ассоциативном массиве в AWK без цикла - PullRequest
0 голосов
/ 16 июня 2020

Интересно, есть ли способ проверить, существует ли значение в ассоциативном массиве в awk, я имею в виду без знания соответствующего ключа и без перебора всего массива, как в Python dict.values(). Давайте возьмем этот пример, где последний оператор if - if ("2" in array) - ЛОЖЬ, и я не знаю, как его написать, поэтому он ИСТИНА.

echo -e 'a\na\nb' | \
awk '
    { array[$1] += 1 }
END {
    for (x in array){
        # key, key[value]
        print x, array[x]
    }
    if ("a" in array){
        # acces key
        print "OK for a key"
    }
    if ("2" == array["a"]){
        # access key[value]
        print "OK for a value when knowing the key"
    }
    if ("2" in array){
        # access value without knowing key ?
        print "OK for any value"}
    } else { 
        print "ERROR"
    }}'

Вывод:

a 2
b 1
OK for a key
OK for a value when knowing the key
ERROR

Есть ли способ проверить, содержит ли массив значения («1» или «2» в этом примере)?

Спасибо!

Ответы [ 2 ]

4 голосов
/ 17 июня 2020

Это просто показывает решение, которое уже упоминал @karakfa , примененное к коду OP, поэтому не принимайте этот ответ, примите его вместо этого.


Вы можете оставить отдельный массив, проиндексированный значениями, которые вы заполняете вместе с вашим основным ассоциативным массивом, и проверьте, что:

$ echo -e 'a\na\nb' |
awk '
    { array[$1] += 1; arrvals[array[$1]] }
END {
    for (x in array){
        # key, key[value]
        print x, array[x]
    }
    if ("a" in array){
        # acces key
        print "OK for a key"
    }
    if ("2" == array["a"]){
        # access key[value]
        print "OK for a value when knowing the key"
    }
    if ("2" in arrvals){
        # access value without knowing key ?
        print "OK for any value"
    } else {
        print "ERROR"
    }
}'
a 2
b 1
OK for a key
OK for a value when knowing the key
OK for any value

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

4 голосов
/ 16 июня 2020

Вы можете сделать что-то вроде этого

$ echo -e 'a\na\nb' | 
  awk '{a[$1]++; b[a[$1]]=$1} 
   END {for(k in a) print k,a[k]; 
        for(k in b) print k,b[k]
        if(2 in b) print "2 is in values"}'

a 2
b 1
1 b
2 a
2 is in values

Обратите внимание, что второй поиск b выполняется по значениям массива a. Однако комментарий уникальности действителен, и если значения не уникальны, вы пропустите соответствующий ключ при обратном поиске. Для проверки типа exist это может быть нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...