문자열 배열이 있고 값에서 단일 문자를 변경하려면 다음을 수행할 수 있습니다.
$ array=(hello world)
$ array[2]=${array[2]:0:2}X${array[2]:3}
$ echo $array[2]
woXld
이 솔루션은 작동하지만 실제로 인덱스의 값을 다시 할당하고 변경된 문자 전후에 원래 값의 양쪽을 확장해야 하기 때문에 매우 긴 문자열의 경우 속도가 느립니다.
배열에 있는 개별 값의 문자 인덱스를 처리하는 것이 가능하지만:
$ echo ${array[2][3]}
X
스칼라 변수의 문자 인덱스에 새 값을 할당합니다.
$ string='hello world'
$ string[9]=X
$ echo $string
hello woXld
유사한 구문은 배열에서 작동하지 않습니다.
$ array[2][3]=X
zsh: no matches found: array[2][3]=X
첫 번째 방법보다 원하는 것을 더 빨리 달성할 수 있는 방법이 있나요?
답변1
이 작업을 우아하게 수행할 수 있는 방법은 없는 것 같습니다. 이는 아마도 zsh
중첩 배열이 실제로 지원되지 않기 때문에 구문이 아직 완전히 개발되지 않았기 때문일 수 있습니다 .
시도해 볼 수 있는 한 가지 방법은 변경하려는 문자를 잘라내는 대신 임시 변수를 사용하는 것입니다.
array=(hello world)
tmp=$array[2]
tmp[3]=X
array[2]=$tmp
실제로 더 빠른지 여부는 배열의 길이 $tmp
또는 전체 배열에 따라 달라지는 것 같습니다.
몇 가지 성능 테스트를 수행한 결과 흥미로운 결과를 얻었습니다. 스칼라만 처리하는 경우 단일 문자를 인덱스(메서드)로 바꾸십시오.ㅏ)
foo[500]=X
왼쪽과 오른쪽 파티션을 분할하고 새 문자열을 만드는 것보다 항상 훨씬 빠른 것 같습니다(방법두번째)
foo=${foo:0:499}X${foo:500}
두 개를 루프에 넣고 길이가 100, 1,000, 10,000, 100,000인 문자열에 대해 100,000번 반복했으며 결과는 다음과 같습니다.
./scalar_A100.zsh 100000: 0.16s
./scalar_A1000.zsh 100000: 0.29s
./scalar_A10000.zsh 100000: 1.66s
./scalar_A100000.zsh 100000: 14.63s
./scalar_B100.zsh 100000: 0.42s
./scalar_B1000.zsh 100000: 1.17s
./scalar_B10000.zsh 100000: 5.39s
./scalar_B100000.zsh 100000: 46.23s
불행하게도 문자열이 배열 내부에 있으면 문자열 길이(또는 배열 자체)에 따라 달라집니다.
배열 테스트를 위해 두 개의 요소가 있는 배열을 사용했습니다. 첫 번째 요소는 "hello"이고 두 번째 요소는 길이가 100~100,000자 사이인 문자열입니다.
상대적으로 짧은 문자열을 제외하고, 이 메소드는ㅏ(임시 변수를 통해)
foo=$bar[2]
foo[500]=O
bar[2]=$foo
실제로 배열 요소를 슬라이스로 바꾸는 것보다 느립니다.
bar[2]=${bar[2]:0:499}O${bar[2]:500}
이는 값이 실제로 임시 변수에 복사되어 배열로 반환되기 때문입니다. 결과는 다음과 같습니다.
./array_A100.zsh 100000: 0.46s
./array_A1000.zsh 100000: 1.84s
./array_A10000.zsh 100000: 10.50s
./array_A100000.zsh 100000: 101.03s
./array_B100.zsh 100000: 0.60s
./array_B1000.zsh 100000: 1.35s
./array_B10000.zsh 100000: 3.17s
./array_B100000.zsh 100000: 22.13s
또한 배열 처리는 모든 경우에 스칼라 처리보다 느립니다.