Apakah ada cara sederhana untuk membalikkan array?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
jadi saya akan mendapatkan: 7 6 5 4 3 2 1
bukannya:1 2 3 4 5 6 7
Apakah ada cara sederhana untuk membalikkan array?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
jadi saya akan mendapatkan: 7 6 5 4 3 2 1
bukannya:1 2 3 4 5 6 7
Saya telah menjawab pertanyaan seperti yang tertulis, dan kode ini membalikkan array. (Mencetak elemen dalam urutan terbalik tanpa membalikkan array hanyalah sebuah for
loop menghitung mundur dari elemen terakhir ke nol.) Ini adalah algoritma "swap first and last" standar.
array=(1 2 3 4 5 6 7)
min=0
max=$(( ${#array[@]} -1 ))
while [[ min -lt max ]]
do
# Swap current first and last elements
x="${array[$min]}"
array[$min]="${array[$max]}"
array[$max]="$x"
# Move closer
(( min++, max-- ))
done
echo "${array[@]}"
Ini berfungsi untuk array dengan panjang ganjil dan genap.
Pendekatan lain yang tidak konvensional:
Keluaran:
Jika
extdebug
diaktifkan, arrayBASH_ARGV
berisi semua parameter posisi dalam fungsi dengan urutan terbalik.sumber
Pendekatan tidak konvensional (semuanya tidak murni
bash
):jika semua elemen dalam array hanya satu karakter (seperti dalam pertanyaan) Anda dapat menggunakan
rev
:jika tidak:
dan jika Anda dapat menggunakan
zsh
:sumber
tac
, sebagai lawan daricat
cukup baik untuk diingat, TERIMA KASIH!rev
, saya perlu menyebutkan bahwarev
tidak akan berfungsi dengan benar untuk angka dengan dua digit. Misalnya elemen array12
menggunakan rev akan dicetak sebagai21
. Cobalah ;-)Jika Anda benar-benar ingin membalikkan dalam array lain:
Kemudian:
Memberi:
Ini harus menangani kasus dengan benar di mana indeks array tidak ada, misalnya Anda miliki
array=([1]=1 [2]=2 [4]=4)
, dalam hal ini pengulangan dari 0 ke indeks tertinggi dapat menambahkan elemen tambahan, kosong.sumber
shellcheck
mencetak dua peringatan:array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
dan untuk:echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
declare
baris.declare -n
tampaknya tidak berfungsi dalam versi bash sebelum 4.3.Untuk menukar posisi array di tempat (bahkan dengan array jarang) (sejak bash 3.0):
Pada eksekusi:
Untuk bash yang lebih lama, Anda perlu menggunakan loop (dalam bash (sejak 2.04)) dan menggunakan
$a
untuk menghindari ruang trailing:Untuk bash sejak 2.03:
Juga (menggunakan operator negasi bitwise) (sejak bash 4.2+):
sumber
Jelek, tidak bisa dipelihara, tapi hanya satu kalimat:
sumber
eval eval echo "'\"\${array[-'{1..${#array[@]}}']}\"'"
.ind=("${!array[@]}");eval eval echo "'\"\${array[ind[-'{1..${#array[@]}}']]}\"'"
Meskipun saya tidak akan mengatakan sesuatu yang baru dan saya juga akan menggunakan
tac
untuk membalikkan array, saya pikir itu akan layak untuk disebutkan di bawah solusi single line menggunakan bash versi 4.4:Pengujian:
Ingat bahwa nama var di dalam read adalah nama sebagai array asli, jadi tidak ada array pembantu yang diperlukan untuk penyimpanan temp.
Implementasi alternatif dengan menyesuaikan IFS:
PS: Saya pikir solusi di atas tidak akan berfungsi dalam
bash
versi di bawah4.4
karenaread
implementasi fungsi bash builtin yang berbeda .sumber
IFS
Versi bekerja tetapi juga mencetak:declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Menggunakan bash4.4-5
. Anda harus menghapus;declare -p array
di akhir baris pertama, lalu bekerja ...declare -p
hanyalah cara cepat untuk membuat bash mencetak array asli (indeks dan konten). Anda tidak perludeclare -p
perintah ini di skrip asli Anda. Jika ada yang salah dalam tugas array Anda, Anda bisa berakhir dalam kasus yang${array[0]}="1 2 3 4 5 6 10 11 12"
= semua nilai disimpan dalam indeks yang sama - menggunakan gema Anda tidak akan melihat perbedaan. Untuk pencetakan array cepat menggunakandeclare -p array
akan mengembalikan Anda indeces array asli dan nilai yang sesuai di setiap indeks.read -d'\n'
metode ini tidak berhasil untuk Anda?read -d'\n'
bekerja dengan baik.Untuk membalikkan array sewenang-wenang (yang mungkin mengandung sejumlah elemen dengan nilai apa pun):
Dengan
zsh
:Dengan
bash
4.4+, mengingat bahwabash
variabel tidak dapat mengandung byte NUL, Anda dapat menggunakan GNUtac -s ''
pada elemen yang dicetak sebagai catatan dibatasi NUL:POSIXly, untuk membalikkan susunan shell POSIX (
$@
, terbuat dari$1
,$2
...):sumber
Solusi bash murni, akan berfungsi sebagai one-liner.
sumber
rev+=( "${array[i]}" )
tampak lebih sederhana.Anda juga dapat mempertimbangkan untuk menggunakan
seq
di freebsd Anda dapat menghilangkan -1 parameter kenaikan:
sumber
Pesta
Atau
Hasil
7 6 5 4 3 2 1
Versi: kapan
sumber
tac
telah disebutkan: unix.stackexchange.com/a/412874/260978 , unix.stackexchange.com/a/467924/260978 , unix.stackexchange.com/a/413176/260978