if (typeof a ! == "undefined" && typeof b ! == "undefined" && typeof c === "string") { call_function(a, b, c); // ... }
Thinking about the conditions themselves: they are a bit strange, although they often occur. Inside “call_function”, type “a” and type “b” will be checked, but not type “c”. On the other hand, the number of supported combinations of the “a” and “b” types supported by the function is of course, and, most likely, is fixed, which means it would be useful to see these combinations. And this post prompted the idea that you can do without conditional operators. So the idea was born to abandon conditional operators in favor of indices. Although the approach is considered within the framework of Javascript, it can be successfully applied in many other languages ​​after taking into account their syntactic features. if(false ||(true &&typeof a === "string" &&typeof b === "string" &&typeof === "string" )||(true &&typeof a === "object" &&typeof b === "string" &&typeof === "string" )||(true &&typeof a === "number" &&typeof b === "string" &&typeof === "string" )||(true &&typeof a === "string" &&typeof b === "object" &&typeof === "string" )||(true &&typeof a === "object" &&typeof b === "object" &&typeof === "string" )||(true &&typeof a === "number" &&typeof b === "object" &&typeof === "string" )||(true &&typeof a === "string" &&typeof b === "number" &&typeof === "string" )||(true &&typeof a === "object" &&typeof b === "number" &&typeof === "string" )||(true &&typeof a === "number" &&typeof b === "number" &&typeof === "string" ) ){ call_function(a, b, c); // ... }
if(true &&(false ||typeof a === "string" ||typeof a === "number" ||typeof a === "object" )&&(false ||typeof b === "string" ||typeof b === "number" ||typeof b === "object" )&&(false ||typeof c === "string" ) ){ call_function(a, b, c); // ... }
But then the question arises, what to do when the combination of argument types is different? Why not cover all possible options at once. Errors of not accounting for some combination of a multitude of conditions are common, and they are difficult to detect. // "a", "b", "c" // // var a_type_index = {'undefined':0, 'object':1, 'boolean':0, 'number':2, 'string':3, 'function':0}[typeof a] var b_type_index = {'undefined':0, 'object':1, 'boolean':0, 'number':2, 'string':3, 'function':0}[typeof b] var c_type_index = {'undefined':0, 'object':0, 'boolean':0, 'number':0, 'string':1, 'function':0}[typeof c] var index = a_type_index + b_type_index*4 + c_type_index*4*4
// "a", "b", "c" // // var types = ['undefined', 'object', 'boolean', 'number', 'string', 'function'] var a_type_index = types.indexOf(typeof a) // a_type_index = +'010230'[a_type_index] var b_type_index = types.indexOf(typeof b) b_type_index = +'010230'[b_type_index] var c_type_index = types.indexOf(typeof c) c_type_index = +'000010'[c_type_index] var index = a_type_index + b_type_index*4 + c_type_index*4*4
;[ //c has incorrect type //b has incorrect type //types a: incorrect, object, number, string show_err_all, show_err_bc, show_err_bc, show_err_bc, //b has object type //types a: incorrect, object, number, string show_err_ac, show_err_c, show_err_c, show_err_c, //b has number type //types a: incorrect, object, number, string show_err_ac, show_err_c, show_err_c, show_err_c, //b has string type //types a: incorrect, object, number, string show_err_ac, show_err_c, show_err_c, show_err_c, //c has string type //b has incorrect type //types a: incorrect, object, number, string show_err_ab, show_err_b, show_err_b, show_err_b, //b has object type //types a: incorrect, object, number, string show_err_a, process, process, process, process, //b has number type //types a: incorrect, object, number, string show_err_a, process, process, process, process, //b has string type //types a: incorrect, object, number, string show_err_a, process, process, process, process ][index](a, b, c)
var b_status = false // var str_status = b_status? 'ok': 'this is false' // var str_status = ['this is false','ok'][+b_status]
The "+" sign converts the b_status variable into a numeric type, since the index must be a number. Notice that the first expression goes to fail the condition. var i_state = 1 // switch switch (i_state) { case 1: console.log('you select 1') break case 2: console.log('you select 2') break default: console.log('you select another') } // i_state = 0|[0,1,2][i_state] // //i_state = 0|{'one':1, 'two':2}[str_state] //i_state = ['one', 'two'].indexOf(str_state)+1 [ function(){ //default console.log('you select another') },function(){ //i_state == 1 console.log('you select 1') },function(){ //i_state == 2 console.log('you select 2') } ][i_state]
Also, as for the ternary operator, the first (zero) case is for false, for the switch, the first is the default case, which is generally convenient, since it is one, its presence is mandatory - this is a certain analogue of zero. function factorial(n){ if(n<=1) return 1; var ret = 1; for(var i=2; i<=n; i++) ret *= i; return ret; } function i_to_insert_order(n, i){ var arr = [] var i_tmp = i for(var j=0; j<n; j++){ var a = i_tmp%(j+1) arr[j] = a i_tmp = ~~(i_tmp/(j+1)) } return arr } function correct(arr){ var n = arr.length; for(var i=1; i<n; i++){ // for(var j=0; j<i; j++){ for(var j=i-1; j>=0; j--){ //if(arr[j]>=arr[i]) arr[j]++ arr[j] += arr[j]>=arr[i] } } } //correct([0,0,0,0,0]) == [4,3,2,1,0] var n = 5 var arr_perm = [] for(var i=0; i<factorial(n); i++){ var arr = i_to_insert_order(n, i) //arr = 0, 0..1, 0..2, 0..3, 0..4 correct(arr) arr_perm.push(arr) } arr_perm.reverse() //arr_perm.length == factorial(n) //arr_perm[0] == [0,1,2,3,4] //arr_perm[-1] == [4,3,2,1,0]
A little bit of clarification: "~~ (x)" - a short recording of "Math.floor (x)", which I learned about from livecoding video . When using a short recording, you should observe the restriction: 0 <= x <= 2147483647.9999998 (selected experimentally ). For comparison, the limit for " Math.floor ": -9007199254740992 <= x <9007199254740993. Array inversion is necessary to obtain permutations in lexicographical order . By index we get (i_to_insert_order) one of the possible sequences for inserting elements. In principle, it is enough to get a permutation of real elements: function insert(arr, i, elem){arr.splice(i, 0, elem)} // var elements = ['word', 'symbol', 'face', 'colors', 'song'] // 35- var order = i_to_insert_order(5, 35) var arr = [] for(var i=0; i<order.length; i++) insert(arr, order[i], elements[i]) //arr == ['word', 'song', 'colors', 'symbol', 'face']
But, in order to see a clear permutation, we emulate this insert. This is what the correct function is for. Perhaps this is not a very good example, because it blurs the main point. const φ = (1+Math.sqrt(5))/2 function fib_by_index(i){ return Math.round(Math.pow(φ, i)/Math.pow(5,0.5)) } fib_by_index(6) == 8 fib_by_index(50) == 12586269025
Source: https://habr.com/ru/post/270241/
All Articles