Comments 14
На мой взгляд, переусложнено, но это может быть из-за ограничений языка. Я недостаточно знаю JS, так что напишу свой вариант на псевдокоде:
val valid_a = ['object', 'string', 'number']
val valid_b = valid_a
val valid_c = ['string', 'undefined']
//список всех возможных валидных троек для параметров
val tuples = decartMultiplication(valid_a, valid_b, valid_c, (a, b, c) -> Tuple3(a, b, c))
val dispatchMap = Map<Tuple3, Closure>
tuples.forEach(tuple -> dispatchMap.put(tuple, (a, b, c) -> call_function(a, b, c))
//usage
val dispatcher = dispatchMap.get(Tuple3(a.type, b.type, c.type))
if (dispatcher != null) dispatcher(a, b, c) else call_badargs(a, b, c)
Вкратце, делаем ассоциативный массив [множество типов аргументов] -> лямбда
Плюсы — мало букв. Минусы — кол-во элементов в мапе растет весьма быстро.
val valid_a = ['object', 'string', 'number']
val valid_b = valid_a
val valid_c = ['string', 'undefined']
//список всех возможных валидных троек для параметров
val tuples = decartMultiplication(valid_a, valid_b, valid_c, (a, b, c) -> Tuple3(a, b, c))
val dispatchMap = Map<Tuple3, Closure>
tuples.forEach(tuple -> dispatchMap.put(tuple, (a, b, c) -> call_function(a, b, c))
//usage
val dispatcher = dispatchMap.get(Tuple3(a.type, b.type, c.type))
if (dispatcher != null) dispatcher(a, b, c) else call_badargs(a, b, c)
Вкратце, делаем ассоциативный массив [множество типов аргументов] -> лямбда
Плюсы — мало букв. Минусы — кол-во элементов в мапе растет весьма быстро.
0
UFO just landed and posted this here
Про память — сейчас добавлю.
Взятие по индексу — точно быстрее, чем последовательный перебор 'else if'-ами. Cомнение вызывает indexOf, но можно обойтись без него и, он как минимум пропорционален числу условий, а может и быстрее. Поиск в хеш-мапе приблизительно O(1), за исключением коллизий, — тут зависит от реализации. Хотя, была ситуация: поиск по длинным строкам в качестве ключа жутко тормозил, пришлось сначала искать по числовому хешу от строки(вычисление которого, впрочем, также вписывается в этот подход). Что касается вычислений, то возведение в целую степень также может быть линейным, но такие алгоритмы врядли еще где остались. Однако, завершения вычисления 50-го число фибоначчи рекурсивным алгоритмом не дождался(отчасти поэтому не включил код в статью), а для индексного результат был без задержки. По-хорошему, конечно, надо бы сделать замеры скорости, но для простых формул — это не актуально. Итого, ответ — возможно, но только для неоптимизированных вариантов: как вы правильно заметили, расходуется дополнительная память, — мы преобразуем временную сложность в пространственную.
Взятие по индексу — точно быстрее, чем последовательный перебор 'else if'-ами. Cомнение вызывает indexOf, но можно обойтись без него и, он как минимум пропорционален числу условий, а может и быстрее. Поиск в хеш-мапе приблизительно O(1), за исключением коллизий, — тут зависит от реализации. Хотя, была ситуация: поиск по длинным строкам в качестве ключа жутко тормозил, пришлось сначала искать по числовому хешу от строки(вычисление которого, впрочем, также вписывается в этот подход). Что касается вычислений, то возведение в целую степень также может быть линейным, но такие алгоритмы врядли еще где остались. Однако, завершения вычисления 50-го число фибоначчи рекурсивным алгоритмом не дождался(отчасти поэтому не включил код в статью), а для индексного результат был без задержки. По-хорошему, конечно, надо бы сделать замеры скорости, но для простых формул — это не актуально. Итого, ответ — возможно, но только для неоптимизированных вариантов: как вы правильно заметили, расходуется дополнительная память, — мы преобразуем временную сложность в пространственную.
0
Время от времени применяю на практике уже лет 25 (правда, не знал как это называется), но обычно только в случаях хорошо ложащихся на классические массивы, когда разворачивание в условные операторы реально является тупой копипастой, когда условия N-го уровня повторяются каждом N-1 уровне, да ещё являются четко дискретными.
0
var type = typeof a + typeof b + typeof c,
callback = {
"objectobjectstring": process,
"objectobjectundefined": process,
"objectstringstring": process,
"objectstringundefined": process,
"objectnumberstring": process,
"objectnumberundefined": process,
"stringobjectstring": process,
"stringobjectundefined": process,
"stringstringstring": process,
"stringstringundefined": process,
"stringnumberstring": process,
"stringnumberundefined": process,
"numberobjectstring": process,
"numberobjectundefined": process,
"numberstringstring": process,
"numberstringundefined": process,
"numbernumberstring": process,
"numbernumberundefined": process
}[type] || process;
callback && callback(a, b, c);
+2
var type = typeof a + typeof b + typeof c;
({
"objectobjectstring": process,
"objectobjectundefined": process,
"objectstringstring": process,
"objectstringundefined": process,
"objectnumberstring": process,
"objectnumberundefined": process,
"stringobjectstring": process,
"stringobjectundefined": process,
"stringstringstring": process,
"stringstringundefined": process,
"stringnumberstring": process,
"stringnumberundefined": process,
"numberobjectstring": process,
"numberobjectundefined": process,
"numberstringstring": process,
"numberstringundefined": process,
"numbernumberstring": process,
"numbernumberundefined": process
}[type] || process)(a, b, c);
+1
var type = (typeof a)[0] + (typeof b)[0] + (typeof c)[0];
({
"oos": process,
"oou": process,
"oss": process,
"osu": process,
"ons": process,
"onu": process,
"sos": process,
"sou": process,
"sss": process,
"ssu": process,
"sns": process,
"snu": process,
"nos": process,
"nou": process,
"nss": process,
"nsu": process,
"nns": process,
"nnu": process
}[type] || process)(a, b, c);
+2
Решил сравнить скорости: jsperf.com/ibp-array-vs-object-index, результат не показателен.
Ваш вариант, мне нравится даже больше :)
Ваш вариант, мне нравится даже больше :)
+2
Обычно составные ключи разделяю подчеркиванием:
var type = typeof a + '_' + typeof b + '_' + typeof c,
callback = {
"object_object_string": process,
"object_object_undefined": process,
...
0
Sign up to leave a comment.
Index-based programming или зачем нам все эти if, switch, тернарный оператор?