gawk asort()의 출력이 순서대로 되지 않는 이유는 무엇입니까?

gawk asort()의 출력이 순서대로 되지 않는 이유는 무엇입니까?

나는 다음 gawk명령을 시도했습니다.

# gawk 'BEGIN{
> var["a"] = 1
> var["g"] = 2
> var["m"] = 3
> var["u"] = 4
> asort(var, test)
> for (i in test)
> print "Index:",i," - value:",test[i]
> }'

다음과 같은 출력을 얻게 됩니다:

인덱스: 4 - 값: 4

인덱스: 1 - 값: 1

인덱스: 2 - 값: 2

인덱스: 3 - 값: 3

그래서 출력이 다음과 같은 순서로 되지 않는 이유가 궁금합니다.

색인: 1

색인: 2

...

이는 배열 값의 올바른 순서이기 때문입니다.

답변1

for (var in array)배열 요소에 액세스하는 순서 는 보장 되지 않습니다 .

루프는 메모리에 저장된 각 요소를 반복하지만, 다음 요소를 저장하는 동안 awk가 메모리에 구멍을 삽입하기로 결정하면 "이상한" 순서가 발생합니다.

그런데 이것은 공식 문서에 설명되어 있습니다. https://www.gnu.org/software/gawk/manual/html_node/Scanning-an-Array.html#index-for-statement-1

따라서 보장된 정렬 배열을 원한다면 다음과 같은 방법을 사용해야 합니다.

element_count = asort(var, test)
for (i=1; i<=element_count; i++)
   print "Index:",i," - value:",test[i]

답변2

asort()인덱스를 1로 대체하기 때문에 정수로 인덱스된 배열에 더 적합하다고 생각합니다.N, 원래 인덱스를 삭제합니다. (이 사례에서 볼 수 있듯이 인덱스 a, g, m, u가 누락되었습니다.)

따라서 정수 인덱스 배열의 경우:

$ cat sort.awk
BEGIN {
    printf("original:\n");
    n = split("hello and bye", a)
    for (i = 1; i <= n; i++) {
        printf("%d %s\n", i, a[i])
    }
    printf("sorted:\n");
    n = asort(a, b);
    for (i = 1; i <= n; i++) {
        printf("%d %s\n", i, b[i])
    }
}

$ awk -f sort
original:
1 hello
2 and
3 bye
sorted:
1 and
2 bye
3 hello

인덱스에 데이터 자체가 포함되어 있으면 다음과 같이 할 수 있습니다 asorti(). 원래 키를 값으로 사용하고 키가 순서대로 정렬되도록 1부터 인덱스를 사용하여 새 배열을 만듭니다.

$ cat sort2.awk
BEGIN {
    d["foo"]=11;
    d["bar"]=22;
    d["doo"]=33;
    n = asorti(d, p);
    for (i = 1; i <= n; i++) {
        printf("%d %s %s\n", i, p[i], d[p[i]])
    }
}
$ awk -f sort2.awk
1 bar 22
2 doo 33
3 foo 11

두 경우 모두에 설명된 문제는흰부엉이의 대답배열 반복을 고려해야 합니다.

관련 정보