Misalnya, seperti ini:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
Apakah ada cara yang lebih baik untuk menulisnya? Sekali lagi, saya tidak mencari jawaban untuk pertanyaan persis di atas, hanya contoh ketika Anda mungkin telah mengulangi operan dalam ekspresi operator terner ...
javascript
conditional-operator
pengguna1354934
sumber
sumber
if
dan bukan yangif/else
just an example of when you might have repeated things in the ternary
jangan ulangi ekspresi yang dihitung. Untuk itulah variabel.3
tidak di index0
ofsomeArray
?Math.max(someArray.indexOf(3), 0)
saja?Jawaban:
Secara pribadi saya menemukan cara terbaik untuk melakukan ini masih
if
pernyataan lama yang baik :sumber
if
pernyataan sebagai pengganti terner. Pernyataan ternary masih sering berguna untuk melakukan pilihan sebagai bagian dari ekspresi.value
setelah baris pertama adalah perantara. Itu tidak berisi nilai yang benar yang kemudian ditetapkan pada baris berikutnya dan dengan demikian menjadi perantara. Hanya setelahif
pernyataan menyimpulkan yangvalue
berisi nilai yang benar. Terner dalam OP adalah solusi yang lebih baik karena tidak pernah memasuki keadaan perantara.value
sini secara teknis bermutasi, yang saya coba hindari.Kode harus dapat dibaca, jadi singkat tidak berarti menjadi singkat berapa pun biayanya - untuk itu Anda harus memposting ulang ke https://codegolf.stackexchange.com/ - jadi saya akan merekomendasikan menggunakan variabel lokal kedua yang diberi nama
index
untuk memaksimalkan pemahaman bacaan ( dengan biaya runtime minimal juga, saya perhatikan):Tetapi jika Anda benar-benar ingin mengurangi ungkapan ini, karena Anda kejam dan sadis bagi rekan kerja atau kolaborator proyek Anda, berikut adalah 4 pendekatan yang dapat Anda gunakan:
1: Variabel sementara dalam sebuah
var
pernyataanAnda dapat menggunakan kemampuan
var
pernyataan untuk mendefinisikan (dan menetapkan) variabel sementara keduaindex
ketika dipisahkan dengan koma:2: Fungsi anonim yang dijalankan sendiri
Opsi lainnya adalah fungsi anonim yang dijalankan sendiri:
3: Operator koma
Ada juga "operator koma" terkenal yang didukung JavaScript, yang juga ada dalam C dan C ++.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
Anda dapat menggunakannya untuk menimbulkan efek samping, dalam hal ini dengan menetapkan kembali ke
value
:Ini berfungsi karena
var value
diinterpretasikan terlebih dahulu (sebagai pernyataan), laluvalue
penugasan paling kiri, paling dalam , dan kemudian operator koma sebelah kanan, lalu operator terner - semua JavaScript legal.4: Tetapkan ulang dalam subekspresi
Komentator @IllusiveBrian menunjukkan bahwa penggunaan operator koma (dalam contoh sebelumnya) tidak diperlukan jika penugasan ke
value
digunakan sebagai subekspresi dalam tanda kurung:Perhatikan bahwa penggunaan negatif dalam ekspresi logika bisa lebih sulit diikuti oleh manusia - jadi semua contoh di atas dapat disederhanakan untuk dibaca dengan mengubah
idx !== -1 ? x : y
keidx == -1 ? y : x
:sumber
indefOf
)var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);
daripada menggunakan koma.var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );
karena hanya satu parameter.Untuk angka
Anda dapat menggunakan
Math.max()
fungsinya.Ini akan membuat batasan hasil dari
0
sampai hasil pertama lebih besar daripada0
jika itu masalahnya. Dan jika hasilnyaindexOf
adalah-1
itu akan mengembalikan 0 as lebih besar dari-1
.Untuk nilai boolean dan boolean-y
Untuk JS tidak ada aturan umum AFAIK khusus karena bagaimana falsy nilai-nilai dievaluasi.
Tetapi jika sesuatu yang dapat membantu Anda sebagian besar waktu adalah atau operator (
||
):Anda harus sangat berhati-hati dengan hal ini, karena dalam contoh pertama Anda,
indexOf
dapat kembali0
dan jika Anda mengevaluasi0 || -1
itu akan kembali-1
karena0
merupakan falsy nilai.sumber
3
atau"y"
tidak di index0
ofsomeArray
?Math.max
contoh?indexOf
mengembalikan indeks elemen dan jika elemen tidak ditemukan mengembalikan -1 sehingga Anda memiliki peluang untuk mendapatkan nomor dari -1 untuk panjang string maka denganMath.max
Anda hanya mengatur batas dari 0 ke panjang untuk menghilangkan peluang untuk mengembalikan -1,0
elemen yang cocok dalam larik, atau0
disetel padaMath.max()
; atau di operator bersyarat di OP. Pertimbangkanvar value = Math.max( ["y"].indexOf("y"), 0 )
. Bagaimana Anda menentukan mana0
yang dikembalikan?0
diteruskan keMath.max()
panggilan, atau0
mencerminkan indeks"y"
dalam array?Tidak juga, gunakan saja variabel lain.
Contoh Anda menggeneralisasi sesuatu seperti ini.
Anda menguji nilai yang dihitung, lalu menetapkan nilai itu ke variabel jika melewati beberapa predikat. Cara untuk menghindari penghitungan ulang nilai yang dihitung sudah jelas: gunakan variabel untuk menyimpan hasilnya.
Saya mengerti maksud Anda - sepertinya harus ada cara untuk melakukan ini yang terlihat sedikit lebih bersih. Tapi saya pikir itulah cara terbaik (secara idiomatis) untuk melakukan ini. Jika Anda sering mengulangi pola ini dalam kode Anda karena suatu alasan, Anda mungkin menulis sedikit fungsi pembantu:
sumber
EDIT: Ini dia, proposal untuk penggabungan Nullary sekarang dalam JavaScript!
Menggunakan
||
const result = a ? a : 'fallback value';
setara dengan
const result = a || 'fallback value';
Jika casting
a
untukBoolean
kembalifalse
,result
akan diberikan'fallback value'
, jika tidak nilaia
.Waspadai kasus edge
a === 0
, yang di-cast kefalse
danresult
akan (salah) ambil'fallback value'
. Gunakan trik seperti ini dengan risiko Anda sendiri.PS. Bahasa seperti Swift memiliki operator penggabung nil (
??
), yang memiliki tujuan serupa. Misalnya, di Swift Anda akan menulisresult = a ?? "fallback value"
yang sangat mirip dengan JavaScriptconst result = a || 'fallback value';
sumber
indexOf()
tidak dapat digunakan dalam pola ini.||
kerja JavaScript? Jika saya memahami Anda dengan benar, maka ia bekerja berbeda dari banyak bahasa utama lainnya (saya terutama memikirkan C dan turunannya [C ++, Java, dll.]) Meskipun itu benar-benar cara||
kerjanya di JavaScript, saya menyarankan agar tidak menggunakan trik seperti ini yang mengharuskan pengelola untuk mengetahui kebiasaan khusus tentang bahasa tersebut. Meskipun trik itu keren, saya akan menganggapnya sebagai praktik yang buruk.-1
. Sekali lagi, saya tidak dapat berbicara untuk JavaScript dan keunikannya, tetapi umumnya-1
akan menjadi nilai sebenarnya, bukan yang salah, dan oleh karena itu jawaban Anda tidak akan berfungsi dalam kasus pertanyaan dan tentu saja bukan kasus umum, melainkan hanya akan berfungsi dalam kasus tertentu ( tapi cukup umum) sub-kasus.Gunakan pemfaktoran ulang variabel ekstrak :
Bahkan lebih baik dengan
const
daripadavar
. Anda juga bisa melakukan ekstraksi tambahan:Dalam prakteknya, menggunakan nama yang lebih bermakna dari
index
,condition
, danvalue
.sumber
Anda mungkin mencari operator penggabungan. Untungnya, kami dapat memanfaatkan
Array
prototipe untuk membuatnya:Ini bisa digeneralisasikan lebih lanjut untuk kasus Anda, dengan menambahkan parameter ke fungsi:
sumber
for (let x in ['b','c']) console.log(x);
cetak0
,1
,"coalesce"
.Saya pribadi lebih suka dua varian:
Murni jika, seperti saran @slebetman
Fungsi terpisah, yang menggantikan nilai yang tidak valid dengan yang default, seperti dalam contoh ini:
sumber
Saya suka jawaban @ slebetman. Komentar di bawahnya mengungkapkan kekhawatiran tentang variabel yang berada dalam "status perantara". jika ini adalah masalah besar bagi Anda, saya sarankan untuk merangkumnya dalam sebuah fungsi:
Kalau begitu telepon saja
Anda dapat melakukan lebih banyak fungsi umum jika Anda memiliki kegunaan untuk fungsi tersebut di tempat lain, tetapi jangan melakukan rekayasa berlebihan jika itu kasus yang sangat spesifik.
Tapi jujur saya hanya akan melakukan sebagai @slebetman kecuali saya perlu menggunakan kembali dari beberapa tempat.
sumber
Ada dua cara yang dapat saya lihat dalam melihat pertanyaan Anda: Anda ingin mengurangi panjang baris, atau Anda secara khusus ingin menghindari pengulangan variabel dalam terner. Yang pertama sepele (dan banyak pengguna lain telah memposting contoh):
dapat (dan seharusnya, diberikan pemanggilan fungsi) dipersingkat seperti:
Jika Anda mencari solusi yang lebih umum yang mencegah pengulangan variabel dalam terner, seperti:
dimana
foo
hanya muncul sekali. Membuang solusi dalam bentuk:karena secara teknis benar tetapi melewatkan intinya, maka Anda kurang beruntung. Ada operator, fungsi, dan metode yang memiliki sintaks singkat yang Anda cari, tetapi konstruksi seperti itu, menurut definisi, tidak operator terner .
Contoh:
javascript, gunakan
||
untuk mengembalikan RHS saat LHS adalahfalsey
:sumber
Gunakan fungsi helper:
Sekarang kode Anda sangat mudah dibaca, dan tidak ada pengulangan.
Hierarki masalah pengkodean adalah:
Sejauh ini semua jawaban di halaman tampaknya benar, tetapi menurut saya versi saya memiliki kejelasan tertinggi, yang lebih penting daripada ringkasan. Jika Anda tidak menghitung fungsi helper — karena dapat digunakan kembali — ini juga yang paling ringkas. Saran yang agak mirip untuk menggunakan fungsi helper sayangnya menggunakan lambda yang, bagi saya, hanya mengaburkan apa yang dilakukannya. Fungsi yang lebih sederhana dengan satu tujuan yang tidak menggunakan lambda, hanya nilai, bagi saya jauh lebih baik.
PS Jika Anda menyukai sintaks ES6:
sumber
translateValueIfEqual
yang menurut saya lebih deskriptif, tetapi saya mengubahnya setelah seseorang mengira itu terlalu panjang. Sama sepertiNz
fungsi di Access, jika Anda mengetahuinya, Anda mengetahuinya, dan jika tidak, Anda tidak. Dalam IDE modern, Anda cukup menekan tombol untuk melompat ke definisi. Dan fallback akan menjadi variabel perantara. Saya tidak benar-benar melihat sisi negatifnya yang besar di sini.Saya pikir
||
operator dapat disesuaikan denganindexOf
:Nilai yang dikembalikan digeser ke atas sebesar 1, menghasilkan 0 dari -1, yang merupakan falsey dan oleh karena itu akan digantikan oleh nilai 1. Kemudian digeser kembali.
Namun, harap diingat bahwa keterbacaan lebih baik daripada menghindari pengulangan.
sumber
Ini adalah solusi sederhana dengan bitwise NOT dan nilai default
-1
yang hasilnya nanti nol.Ini bekerja pada dasarnya dengan bitwise NOT ganda, yang mengembalikan nilai asli atau nilai default, yang setelah menerapkan bitwise NOT mengembalikan nol.
Mari kita lihat tabel kebenaran:
sumber
Anda bisa menggunakan penugasan ulang:
&&
operator untuk penugasan ulang, karena jika kondisi pertama salah, ekspresi kedua tidak akan dievaluasiEx.
Tampilkan cuplikan kode
sumber
someArray.indexOf
hanya dilakukan sekalivalue
.-1
dan0
; jika tidak makamax()
akan menjadi pilihan terbaikAgain, not seeking an answer to the exact question above
, yang meninggalkan pertanyaan pada interpretasi;)Mengingat kode contoh di Question, tidak jelas bagaimana cara menentukannya
3
ini atau tidak diatur pada indeks0
darisomeArray
.-1
dikembalikan dari.indexOf()
akan menjadi berharga dalam hal ini, untuk tujuan mengecualikan non-pertandingan yang dianggap cocok.Jika
3
tidak termasuk dalam array,-1
akan dikembalikan. Kita bisa menambahkan1
ke hasil.indexOf()
untuk mengevaluasi sebagaifalse
hasil-1
, di mana diikuti oleh||
OR
operator dan0
. Jikavalue
direferensikan, kurangi1
untuk mendapatkan indeks elemen array atau-1
.Yang mengarah kembali ke hanya menggunakan
.indexOf()
dan memeriksa-1
pada suatuif
kondisi. Atau, mendefinisikanvalue
sebagaiundefined
untuk menghindari kemungkinan kebingungan dengan hasil yang sebenarnya dari kondisi dievaluasi berkaitan dengan referensi asli.sumber
Terner itu seperti jika-lain, jika Anda tidak membutuhkan bagian lain, mengapa tidak hanya satu jika saja ..
sumber
Untuk kasus khusus ini, Anda dapat menggunakan hubungan arus pendek dengan
||
operator logika . Sebagai0
dianggap falsy, Anda dapat menambahkan1
ke indeks, sehingga, jikaindex+1
ini0
maka Anda akan mendapatkan sisi kanan dari hasil Anda logis-atau, jika tidak, Anda akan mendapatkan Andaindex+1
. Karena hasil yang Anda inginkan diimbangi1
, Anda kemudian dapat menguranginya1
untuk mendapatkan indeks Anda:sumber