배열의 배열에서 항목을 검색하는 방법은 무엇입니까?

배열의 배열에서 항목을 검색하는 방법은 무엇입니까?

안녕하세요, StackExchange 전문가 여러분!

저는 macOS용 zsh 프로젝트를 작업 중입니다. 조판을 사용하여 값을 보관할 세 개의 연관 배열과 개별 배열을 참조하는 네 번째 배열을 만들었습니다. 각 멤버 배열에서 키/값 쌍을 검색하기 위해 arrCollection을 반복할 수 있습니까? 아래 배열의 키는 내 프로덕션 스크립트와 다릅니다. 이는 단지 키 인덱스일 뿐 연관 배열에서 찾을 수 있는 더 설명적인 키가 아닙니다.

다음과 같이 매개변수 확장을 사용할 수 있을 것 같습니다.

for k in $(sort <<< "${(kvF)arrCollection}"); do
   echo "$arrCollection["${(kvF)k}"]"
done

그러나 나는 완전히 옳지 않습니다. 누구든지 도와줄 수 있나요? 예상되는 출력은 개행 문자로 구분된 세 배열 모두의 모든 항목 목록입니다.

다음은 전체 스크립트 예입니다. 사용법: arrTest.sh showAll

#!/bin/zsh

key=$1

typeset -A arrOne arrTwo arrThree
typeset -A arrCollection

#Plan is to use an array of arrays so that a for loop can be used later to loop
#through each key/value pair looking for a value that matches some pattern in an if statement
#(if statement not included here). In the showAll case, how can I use parameter expansion to print all
#of the values in each array? The if statement will further constrict what is actually echoed based on its
#value.

arrOne[1]="First"
arrOne[2]="Second"
arrOne[3]="Third"
arrOne[4]="Fourth"

arrTwo[1]="Purple"
arrTwo[2]="Orange"
arrTwo[3]="Red"
arrTwo[4]="Green"
arrTwo[5]="Blue"

arrThree[1]="First"
arrThree[2]="Red"
arrThree[3]="Planet"
arrThree[4]="Sun"
arrThree[5]="Moon"
arrThree[6]="Star"

#Array of arrays
arrCollection[1]=arrOne
arrCollection[2]=arrTwo
arrCollection[3]=arrThree

#Expect a parameter
if [ -z "$key" ]
then
    echo "Please enter a parameter"
else
    case "$key" in
    showAll)
        for k in $(sort <<< "${(kvF)arrCollection}"); do
            #This is the part I am having trouble with
            echo "$arrCollection["${(kvF)k}"]"
        done
        exit 1
    ;;
    *)
        echo "Something goes here"
        exit 1
    ;;
    esac
fi

답변1

키가 1부터 시작하는 연속적인 십진수일 때 일반 배열 대신 연관 배열을 사용하는 이유가 확실하지 않지만 원하는 것을 올바르게 이해하면 다음을 수행할 수 있습니다.

for key in "${(nok@)arrCollection}"; do
  print -r - "Assoc $key: $arrCollection[$key]"
  printf ' "%s" => "%s"\n' "${(@kvP)arrCollection[$key]}"
done

샘플은 다음과 같은 내용을 제공해야 합니다.

Assoc 1: arrOne
 "3" => "Third"
 "4" => "Fourth"
 "1" => "First"
 "2" => "Second"
Assoc 2: arrTwo
 "3" => "Red"
 "4" => "Green"
 "5" => "Blue"
 "1" => "Purple"
 "2" => "Orange"
Assoc 3: arrThree
 "3" => "Planet"
 "4" => "Sun"
 "5" => "Moon"
 "6" => "Star"
 "1" => "First"
 "2" => "Red"

또는 연관된 각 멤버를 키를 기준으로 숫자순으로 정렬할 수 있습니다.

for key in "${(nok@)arrCollection}"; do
  print -r - "Assoc $key: $arrCollection[$key]"
  for assoc_key in "${(@knoP)arrCollection[$key]}"; do
    printf ' "%s" => "%s"\n' "$assoc_key" "${${(P)arrCollection[$key]}[$assoc_key]}"
  done
done

그러면 다음이 제공됩니다.

Assoc 1: arrOne
 "1" => "First"
 "2" => "Second"
 "3" => "Third"
 "4" => "Fourth"
Assoc 2: arrTwo
 "1" => "Purple"
 "2" => "Orange"
 "3" => "Red"
 "4" => "Green"
 "5" => "Blue"
Assoc 3: arrThree
 "1" => "First"
 "2" => "Red"
 "3" => "Planet"
 "4" => "Sun"
 "5" => "Moon"
 "6" => "Star"

o위의 키는 n(순서) 및 (번호)를 사용하여 정렬됩니다.매개변수 확장 플래그. 이러한 요소와 비교할 때 요소는 10진수 시퀀스로 구성된 부분을 제외하고 로케일 조합을 사용하여 비교됩니다. 십진수 시퀀스는 십진수 정수로 해석되어 숫자로 비교됩니다.

sort이는 GNU 구현에서 -V/ 옵션을 사용하여 수행하는 작업과 유사합니다 --version-sort.

예를 들어 foo2-3before foo10-3및 before 에 표시되지만 양의 십진 정수( before 및 before 에도 표시됨 ) foo2-10이외의 숫자에는 사용할 수 없습니다 .-2-102.32.10

sort다른 임의의 기준을 사용하여 정렬하려면 zsh에 내장된 이 작업을 수행하는 복잡한 방법이 있지만 요소에 NL 또는 NUL 문자가 포함되지 않고 비어 있지 않다는 것을 보장할 수 있다면 더 쉬울 수 있습니다.

GNU를 예로 들어보겠습니다 sort.

for key in ${(0)"$(print -rNC1 -- ${(k)arrCollection} | sort -zg)"}

Null이 아닌 키를 숫자로 반복하지만 이번에는 다양한 숫자 표현(0x20, 1e-1, 무한대, -20, 0x3.fp5... 포함)을 지원합니다.

위의 내용은 NUL로 구분된 레코드를 사용하여 목록을 제공 sort하고 출력을 분할하므로 키에 NUL 문자가 포함되어 있지 않은 것으로 가정됩니다. 대신 NL/LF 문자를 사용하려면 을 삭제 -N하고 로 -z변경하세요 .(0)(f)


1 및 NUL 문자는 표준 비교 API에서 차단하므로 별도로 처리해야 합니다.

관련 정보