Cara menulis ekspresi operator terner (alias jika) tanpa mengulang sendiri

104

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 ...

pengguna1354934
sumber
2
Jadi, ifdan bukan yangif/else
zer00ne
53
just an example of when you might have repeated things in the ternaryjangan ulangi ekspresi yang dihitung. Untuk itulah variabel.
vol7ron
4
Bagaimana kita menentukan bahwa 3tidak di index 0of someArray?
tamu271314
3
Apa tujuanmu disini? Apakah Anda mencoba untuk mengurangi panjang garis, atau secara khusus mencoba untuk menghindari pengulangan variabel di terner? Yang pertama dimungkinkan, yang terakhir tidak (setidaknya, tidak menggunakan terner).
asgallant
5
Mengapa tidak digunakan Math.max(someArray.indexOf(3), 0)saja?
301_Moved_Permanently

Jawaban:

176

Secara pribadi saya menemukan cara terbaik untuk melakukan ini masih ifpernyataan lama yang baik :

var value = someArray.indexOf(3);
if (value === -1) {
  value = 0;
}
slebetman
sumber
32
Untuk lebih jelasnya, jawaban ini menganjurkan penggunaan variabel untuk menyimpan hasil antara, bukan penggunaan ifpernyataan sebagai pengganti terner. Pernyataan ternary masih sering berguna untuk melakukan pilihan sebagai bagian dari ekspresi.
Triptych
4
@ Triptych: Lihat lagi. Itu tidak menggunakan variabel perantara sama sekali. Sebagai gantinya, ia menetapkan hasil langsung ke variabel final dan kemudian menimpanya jika kondisinya terpenuhi.
slebetman
14
Salah. Nilai yang disimpan valuesetelah baris pertama adalah perantara. Itu tidak berisi nilai yang benar yang kemudian ditetapkan pada baris berikutnya dan dengan demikian menjadi perantara. Hanya setelah ifpernyataan menyimpulkan yang valueberisi nilai yang benar. Terner dalam OP adalah solusi yang lebih baik karena tidak pernah memasuki keadaan perantara.
Jack Aidley
44
@JackAidley: "Terner dalam OP adalah solusi yang lebih baik karena tidak pernah memasuki keadaan perantara." - Saya harus tidak setuju. Ini jauh lebih mudah dibaca daripada kode OP, dan sepenuhnya idiomatis. Itu juga membuat bug dalam logika OP sedikit lebih jelas bagi saya (Yaitu, apa yang terjadi jika indexOf () mengembalikan nol? Bagaimana Anda membedakan nol "nyata" dari nol "tidak ditemukan"?).
Kevin
2
ini mendekati apa yang akan saya lakukan, kecuali bahwa di valuesini secara teknis bermutasi, yang saya coba hindari.
Dave Cousineau
102

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 indexuntuk memaksimalkan pemahaman bacaan ( dengan biaya runtime minimal juga, saya perhatikan):

var index = someArray.indexOf( 3 );
var value = index == -1 ? 0 : index;

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 varpernyataan

Anda dapat menggunakan kemampuan varpernyataan untuk mendefinisikan (dan menetapkan) variabel sementara kedua indexketika dipisahkan dengan koma:

var index = someArray.indexOf(3), value = index !== -1 ? index: 0;

2: Fungsi anonim yang dijalankan sendiri

Opsi lainnya adalah fungsi anonim yang dijalankan sendiri:

// Traditional syntax:
var value = function( x ) { return x !== -1 ? x : 0 }( someArray.indexOf(3) );

// ES6 syntax:
var value = ( x => x !== -1 ? x : 0 )( someArray.indexOf(3) );

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 menggunakan operator koma saat Anda ingin menyertakan beberapa ekspresi di lokasi yang membutuhkan ekspresi tunggal.

Anda dapat menggunakannya untuk menimbulkan efek samping, dalam hal ini dengan menetapkan kembali ke value:

var value = ( value = someArray.indexOf(3), value !== -1 ? value : 0 );

Ini berfungsi karena var valuediinterpretasikan 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 valuedigunakan sebagai subekspresi dalam tanda kurung:

var value = ( ( value = someArray.indexOf(3) ) !== -1 ? value : 0 );

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 : yke idx == -1 ? y : x:

var value = ( ( value = someArray.indexOf(3) ) == -1 ? 0 : value );
Dai
sumber
97
Semua ini adalah jenis pengkodean "pintar" yang akan membuat saya menatapnya selama beberapa detik sebelum berpikir "ya, saya rasa itu berhasil." Mereka tidak membantu dengan kejelasan, dan karena kode lebih banyak dibaca daripada yang tertulis itu lebih penting.
Gavin S. Yancey
18
@ g.rocket approach 1 100% dapat dibaca dan jelas, dan satu-satunya cara untuk pergi jika Anda ingin menghindari pengulangan (itu bisa sangat berbahaya jika Anda memanggil beberapa fungsi yang kompleks dan bermasalah daripada yang sederhana indefOf)
edc65
5
Setuju, # 1 sangat mudah dibaca dan dipelihara, dua lainnya tidak begitu banyak.
forgivenson
6
Untuk # 3, saya yakin Anda dapat menyederhanakan var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);daripada menggunakan koma.
IllusiveBrian
2
Dalam contoh kedua, fungsi anonim yang dijalankan sendiri, Anda dapat menghilangkan tanda kurung dari fungsi panah. var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );karena hanya satu parameter.
Alex Char
54

Untuk angka

Anda dapat menggunakan Math.max()fungsinya.

var value = Math.max( someArray.indexOf('y'), 0 );

Ini akan membuat batasan hasil dari 0sampai hasil pertama lebih besar daripada 0jika itu masalahnya. Dan jika hasilnya indexOfadalah -1itu 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 ( ||):

// Instead of
var variable = this_one === true ? this_one : or_this_one;
// you can use
var variable = this_one || or_this_one;

Anda harus sangat berhati-hati dengan hal ini, karena dalam contoh pertama Anda, indexOfdapat kembali 0dan jika Anda mengevaluasi 0 || -1itu akan kembali -1karena 0merupakan falsy nilai.

Crisoforo Gaspar
sumber
2
Terima kasih. Saya rasa contoh saya buruk. Saya hanya memberikan contoh umum haha ​​tidak mencari solusi untuk pertanyaan yang tepat. Saya telah menghadapi beberapa skenario seperti contoh di mana saya ingin menggunakan terner, tetapi akhirnya mengulangi :(
user1354934
1
Pada contoh pertama, bagaimana kita menentukan bahwa 3atau "y"tidak di index 0of someArray?
tamu271314
Pada Math.maxcontoh? indexOfmengembalikan indeks elemen dan jika elemen tidak ditemukan mengembalikan -1 sehingga Anda memiliki peluang untuk mendapatkan nomor dari -1 untuk panjang string maka dengan Math.maxAnda hanya mengatur batas dari 0 ke panjang untuk menghilangkan peluang untuk mengembalikan -1,
Crisoforo Gaspar
@mitogh Logika pada kode di OP menciptakan masalah, meskipun contoh umum; di mana 0 bisa menunjukkan indeks 0elemen yang cocok dalam larik, atau 0disetel pada Math.max(); atau di operator bersyarat di OP. Pertimbangkan var value = Math.max( ["y"].indexOf("y"), 0 ). Bagaimana Anda menentukan mana 0yang dikembalikan? 0diteruskan ke Math.max()panggilan, atau 0mencerminkan indeks "y"dalam array?
tamu271314
@ guest271314 Pemikiran yang bagus, tapi menurut saya itu tergantung pada konteks, apakah itu masalah atau tidak. Mungkin tidak masalah dari mana asalnya 0, dan satu-satunya yang penting adalah bukan -1. Contoh: mungkin Anda perlu memilih item dari array. Anda menginginkan item tertentu (di OP, nomor 3), tetapi jika itu tidak ada dalam array, Anda masih memerlukan item, dan Anda baik-baik saja dengan default ke item pertama apa pun, dengan asumsi Anda tahu array itu tidak ' t kosong.
Kev
27

Tidak juga, gunakan saja variabel lain.

Contoh Anda menggeneralisasi sesuatu seperti ini.

var x = predicate(f()) ? f() : default;

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.

var computed = f();
var x = predicate(computed) ? computed : default;

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:

var setif = (value, predicate, default) => predicate(value) ? value : default;
var x = setif(someArray.indexOf(3), x => x !== -1, 0)
Triptych
sumber
17

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 auntuk Booleankembali false, resultakan diberikan 'fallback value', jika tidak nilai a.


Waspadai kasus edge a === 0, yang di-cast ke falsedan resultakan (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 menulis result = a ?? "fallback value"yang sangat mirip dengan JavaScriptconst result = a || 'fallback value';

Lyubomir
sumber
3
PHP (> 7.0) dan C # juga mendukung operator penggabungan null. Gula sintaksis tapi pasti enak.
Hissvard
5
Ini hanya berfungsi jika fungsi mengembalikan nilai salah saat gagal, tetapi indexOf()tidak dapat digunakan dalam pola ini.
Barmar
1
Benar, tapi dia tidak menanyakan contoh spesifik> "Sekali lagi, tidak mencari jawaban untuk pertanyaan persis di atas, hanya contoh ketika Anda mungkin telah mengulangi hal-hal di terner" <, ingatlah dia lebih suka menanyakan cara umum untuk mengganti terner berulang (result = a? a: b). Dan mengulang terner sama dengan || (hasil = a || b)
Lyubomir
2
Apakah itu benar - benar cara ||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.
Loduwijk
1
Juga perhatikan bahwa pertanyaannya adalah membandingkan nilai dengan -1. Sekali lagi, saya tidak dapat berbicara untuk JavaScript dan keunikannya, tetapi umumnya -1akan 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.
Loduwijk
8

Gunakan pemfaktoran ulang variabel ekstrak :

var index = someArray.indexOf(3);
var value = index !== -1 ? index : 0

Bahkan lebih baik dengan constdaripada var. Anda juga bisa melakukan ekstraksi tambahan:

const index = someArray.indexOf(3);
const condition = index !== -1;
const value = condition ? index : 0;

Dalam prakteknya, menggunakan nama yang lebih bermakna dari index, condition, dan value.

const threesIndex = someArray.indexOf(3);
const threeFound = threesIndex !== -1;
const threesIndexOrZero = threeFound ? threesIndex : 0;
Dave Cousineau
sumber
Apa itu "variabel ekstrak"? Apakah itu istilah yang sudah mapan?
Peter Mortensen
6

Anda mungkin mencari operator penggabungan. Untungnya, kami dapat memanfaatkan Arrayprototipe untuk membuatnya:

Array.prototype.coalesce = function() {
    for (var i = 0; i < this.length; i++) {
        if (this[i] != false && this[i] != null) return this[i];
    }
}

[null, false, 0, 5, 'test'].coalesce(); // returns 5

Ini bisa digeneralisasikan lebih lanjut untuk kasus Anda, dengan menambahkan parameter ke fungsi:

Array.prototype.coalesce = function(valid) {
    if (typeof valid !== 'function') {
        valid = function(a) {
            return a != false && a != null;
        }
    }

    for (var i = 0; i < this.length; i++) {
        if (valid(this[i])) return this[i];
    }
}

[null, false, 0, 5, 'test'].coalesce(); // still returns 5
[null, false, 0, 5, 'test'].coalesce(function(a){return a !== -1}); // returns null
[null, false, 0, 5, 'test'].coalesce(function(a){return a != null}); //returns false
Tyzoid
sumber
Menambah prototipe array berisiko, karena elemen baru menjadi indeks di dalam setiap array. Ini berarti bahwa iterasi melalui indeks juga mencakup metode baru: for (let x in ['b','c']) console.log(x);cetak 0, 1, "coalesce".
Charlie Harding
@CharlieHarding True, tetapi umumnya tidak disarankan untuk menggunakan operator for-in saat melakukan perulangan melalui array. Lihat stackoverflow.com/a/4374244/1486100
Tyzoid
6

Saya pribadi lebih suka dua varian:

  1. Murni jika, seperti saran @slebetman

  2. Fungsi terpisah, yang menggantikan nilai yang tidak valid dengan yang default, seperti dalam contoh ini:

function maskNegative(v, def) {
  return v >= 0 ? v : def;
}

Array.prototype.indexOfOrDefault = function(v, def) {
  return maskNegative(this.indexOf(v), def);
}

var someArray = [1, 2];
console.log(someArray.indexOfOrDefault(2, 0)); // index is 1
console.log(someArray.indexOfOrDefault(3, 0)); // default 0 returned
console.log(someArray.indexOfOrDefault(3, 123)); // default 123 returned

Iłya Bursov
sumber
1
+1, opsi 2 menghormati maksud sebaris pertanyaan, dapat diterapkan secara efisien ke bahasa lain selain javascript, dan mempromosikan modularitas.
Devsman
5

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:

function get_value(arr) {
   var value = arr.indexOf(3);
   if (value === -1) {
     value = 0;
   }
   return value;
}

Kalau begitu telepon saja

var value = get_value( someArray );

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.

Adam
sumber
4

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):

var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0;

dapat (dan seharusnya, diberikan pemanggilan fungsi) dipersingkat seperti:

var value = someArray.indexOf(3);
value = value !== -1 ? value : 0;

Jika Anda mencari solusi yang lebih umum yang mencegah pengulangan variabel dalam terner, seperti:

var value = conditionalTest(foo) ? foo : bar;

dimana foohanya muncul sekali. Membuang solusi dalam bentuk:

var cad = foo;
var value = conditionalTest(foo) ? cad : bar;

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 adalah falsey:

var value = foo || bar; // equivalent to !foo ? bar : foo
asgallant
sumber
1
Pertanyaannya diberi tag javascript dan tidak menyebutkan C #. Hanya bertanya-tanya mengapa Anda mengakhiri dengan contoh spesifik C #.
Loduwijk
Saya melewatkan tag javascript pada pertanyaan; menghapus C #.
asgallant
3

Gunakan fungsi helper:

function translateValue(value, match, translated) {
   return value === match ? translated : value;
}

Sekarang kode Anda sangat mudah dibaca, dan tidak ada pengulangan.

var value = translateValue(someArray.indexOf(3), -1, 0);

Hierarki masalah pengkodean adalah:

  1. Benar (termasuk kinerja sebenarnya atau masalah SLA)
  2. Bersih
  3. Ringkas
  4. Cepat

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:

const translateValue = (value, match, translated) => value === match ? translated : value;
let value = translateValue(someArray.indexOf(3), -1, 0); // or const
ErikE
sumber
2
"versi saya memiliki kejelasan tertinggi" - Saya tidak setuju. Nama fungsi terlalu panjang dan parameter penamaan input dan output sama sekali tidak membantu.
adelphus
Jadi, bisakah Anda menyarankan nama yang lebih baik? Saya akan senang menghibur mereka. Keluhan Anda hanya tentang kosmetik, jadi mari kita perbaiki kosmetiknya. Baik? Kalau tidak, Anda hanya membuang sepeda.
ErikE
Dalam beberapa kasus, fungsi pembantu seperti itu bisa berguna. Dalam kasus ini, jika hanya mengganti kasus tertentu dari operator terner, fungsi Anda akan menjadi kurang jelas. Saya tidak akan mengingat apa fungsi fungsi Anda, dan saya harus mencarinya lagi setiap kali saya menemukannya, dan saya tidak akan pernah ingat untuk menggunakannya.
Loduwijk
1
@ Aaron Itu penilaian yang masuk akal untuk kasus penggunaan tertentu. Untuk apa nilainya, nama fungsi asli saya translateValueIfEqualyang menurut saya lebih deskriptif, tetapi saya mengubahnya setelah seseorang mengira itu terlalu panjang. Sama seperti Nzfungsi 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.
ErikE
1
Ini hanya untuk menunjukkan bahwa jika Anda mengajukan pertanyaan yang sama kepada 5 teknisi berbeda, Anda akan mendapatkan 10 jawaban berbeda.
Loduwijk
2

Saya pikir ||operator dapat disesuaikan dengan indexOf:

var value = ((someArray.indexOf(3) + 1) || 1) - 1;

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.

IllidanS4 ingin Monica kembali
sumber
2

Ini adalah solusi sederhana dengan bitwise NOT dan nilai default -1yang hasilnya nanti nol.

index = ~(~array.indexOf(3) || -1);

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:

 indexOf    ~indexOf   boolean    default     value      result         comment
---------  ---------  ---------  ---------  ---------  ---------  ------------------
      -1          0     falsy          -1         -1          0   take default value
       0         -1    truthy                     -1          0
       1         -2    truthy                     -2          1
       2         -3    truthy                     -3          2
Nina Scholz
sumber
0

Anda bisa menggunakan penugasan ulang:

  • menginisialisasi variabel ke satu nilai
  • gunakan serialisasi &&operator untuk penugasan ulang, karena jika kondisi pertama salah, ekspresi kedua tidak akan dievaluasi

Ex.

var value = someArray.indexOf(3);
value == -1 && (value=0);

vol7ron
sumber
3
@MinusFour Sampai derajat tertentu. Variabel diulang, bukan ekspresi someArray.indexOfhanya dilakukan sekali
vol7ron
Anda ulangi value.
MinusFour
3
@MinusFour Benar, tetapi ini lebih berguna untuk ekspresi yang lebih besar, mengulangi variabel tidak signifikan dibandingkan dengan menyimpan operasi. Dugaan saya adalah OP tidak bekerja dengan -1dan 0; jika tidak maka max()akan menjadi pilihan terbaik
vol7ron
2
Benar ... tapi pertanyaannya adalah ... "Bagaimana menulis terner tanpa mengulang sendiri"
MinusFour
4
Ia juga mengatakan Again, not seeking an answer to the exact question above, yang meninggalkan pertanyaan pada interpretasi;)
vol7ron
0

Mengingat kode contoh di Question, tidak jelas bagaimana cara menentukannya 3 ini atau tidak diatur pada indeks 0dari someArray. -1dikembalikan dari .indexOf()akan menjadi berharga dalam hal ini, untuk tujuan mengecualikan non-pertandingan yang dianggap cocok.

Jika 3tidak termasuk dalam array, -1akan dikembalikan. Kita bisa menambahkan 1ke hasil .indexOf()untuk mengevaluasi sebagai falsehasil -1, di mana diikuti oleh || ORoperator dan0 . Jika valuedireferensikan, kurangi 1untuk mendapatkan indeks elemen array atau -1.

Yang mengarah kembali ke hanya menggunakan .indexOf()dan memeriksa -1pada suatu ifkondisi. Atau, mendefinisikan valuesebagai undefineduntuk menghindari kemungkinan kebingungan dengan hasil yang sebenarnya dari kondisi dievaluasi berkaitan dengan referensi asli.

var someArray = [1,2,3];
var value = someArray.indexOf(3) + 1 || 1;
console.log(value -= 1);

var someArray = [1,2,3];
var value = someArray.indexOf(4) + 1 || 1;
// how do we know that `4` is not at index `0`?
console.log(value -= 1);

var someArray = [1,2,3];
var value = someArray.indexOf(4) + 1 || void 0;
// we know for certain that `4` is not found in `someArray`
console.log(value, value = value || 0);

tamu271314
sumber
0

Terner itu seperti jika-lain, jika Anda tidak membutuhkan bagian lain, mengapa tidak hanya satu jika saja ..

if ((value = someArray.indexOf(3)) < 0) value = 0;
Khaled.K
sumber
0

Untuk kasus khusus ini, Anda dapat menggunakan hubungan arus pendek dengan ||operator logika . Sebagai 0dianggap falsy, Anda dapat menambahkan 1ke indeks, sehingga, jika index+1ini 0maka Anda akan mendapatkan sisi kanan dari hasil Anda logis-atau, jika tidak, Anda akan mendapatkan Anda index+1. Karena hasil yang Anda inginkan diimbangi 1, Anda kemudian dapat menguranginya 1untuk mendapatkan indeks Anda:

const someArray = [1, 2, 3, 4];
const v = ((someArray.indexOf(3)+1) || 1)-1;
console.log(v);

Nick Parsons
sumber