17.01.2013, 07:23
|
Новичок на форуме
|
|
Регистрация: 17.01.2013
Сообщений: 5
|
|
Оптимальный способ построения сложного условия с множеством параметров
Всем привет, столкнулся со следующей задачей в которой мне нужен совет:
Существует JSON объект который имеет элементы с множеством свойств, некоторые из которых имеют значение 1 или 0. Моя задача отфильтровать JSON объект по нажатию кнопок соответствующих свойств объекта. Например, нажата кнопка wifi, значение элемента переходит в 1 и затем считываются состояние фильтров и выполняется поиск по объекту. Состояние считывается из значений кнопок и выглядит следующим образом: 111 - все нажаты, 000 - ничего не нажато,100 - нажата первая кнопка.
Вот кусочек кода, как сейчас реализовано:
rest = $.grep(restaurants, function(e){
switch (state_of_buttons) {
// All buttons are pressed
case '111':
if (city_id != 0) {
return (e.city_id == city_id);
} else {
return e ;
}
break
// There's no pressed buttons
case '000':
if (city_id != 0) {
return (e.car_distribution == route && e.round_the_clock == schedule && e.wifi == wifi && e.city_id == city_id);
} else {
return (e.car_distribution == route && e.round_the_clock == schedule && e.wifi == wifi);
}
break
А теперь суть проблемы - такой подход плохой, при добавлении всего 1 кнопки (сервиса по которому будет фильтроваться JSON объект) количество перестановок становится равным 16 - все это оформлять довольно тяжело да и странно, на мой взгляд.
Пожалуйста поделитесь своими соображениями на счет оптимального способа построения сложного условия. Что то не хочется делать через 0000,1111,0101,1000 и так далее....
Последний раз редактировалось Уханов Сергей, 17.01.2013 в 09:02.
|
|
17.01.2013, 16:04
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
Сообщение от Уханов Сергей
|
Пожалуйста поделитесь своими соображениями на счет оптимального способа построения сложного условия. Что то не хочется делать через 0000,1111,0101,1000 и так далее....
|
1. Комплексные зависимости от них никуда не деться, а побитовые и межбитовые(двух и трёх) выносить в отдельные функции
Последний раз редактировалось Deff, 18.01.2013 в 07:38.
|
|
18.01.2013, 07:27
|
Новичок на форуме
|
|
Регистрация: 17.01.2013
Сообщений: 5
|
|
Спасибо за ответ! Была конечно мысль накопить строчку по фильтрам и выполнить в eval, но народ не советует. Очень жаль...
|
|
18.01.2013, 14:24
|
Новичок на форуме
|
|
Регистрация: 17.01.2013
Сообщений: 5
|
|
Спасибо за путеводную нить, гражданин-трансгуманист
Буду пытаться реализовать по вашей концепции, нужно будет только додумать некоторые моменты: например, при сочетании фильтров 1101 должны учитываться 1000,0100,0001, 1100, 0101, 1001 иначе фильры будут работать некорректно, т.е. сделать аналог:
case '1101':
return (city_id != 0) ? ((e.round_the_clock == schedule && e.car_distribution == route && e.promo == promo && e.city_id == city_id) ||
(e.round_the_clock == 0 && e.car_distribution == 0 && e.promo == 1 && e.city_id == city_id) ||
(e.round_the_clock == 0 && e.car_distribution == 1 && e.promo == 0 && e.city_id == city_id) ||
(e.round_the_clock == 0 && e.car_distribution == 1 && e.promo == 1 && e.city_id == city_id) ||
(e.round_the_clock == 1 && e.car_distribution == 0 && e.promo == 0 && e.city_id == city_id) ||
(e.round_the_clock == 1 && e.car_distribution == 0 && e.promo == 1 && e.city_id == city_id) ||
(e.round_the_clock == 1 && e.car_distribution == 1 && e.promo == 0 && e.city_id == city_id))
: ((e.round_the_clock == schedule && e.car_distribution == route && e.promo == promo) ||
(e.round_the_clock == 0 && e.car_distribution == 0 && e.promo == 1) ||
(e.round_the_clock == 0 && e.car_distribution == 1 && e.promo == 0) ||
(e.round_the_clock == 0 && e.car_distribution == 1 && e.promo == 1) ||
(e.round_the_clock == 1 && e.car_distribution == 0 && e.promo == 0) ||
(e.round_the_clock == 1 && e.car_distribution == 0 && e.promo == 1) ||
(e.round_the_clock == 1 && e.car_distribution == 1 && e.promo == 0));
|
|
18.01.2013, 19:12
|
Новичок на форуме
|
|
Регистрация: 17.01.2013
Сообщений: 5
|
|
Нда, действительно проблема.... Составные условия не могу использовать при таком подходе. Как думаете есть возможность построить условное выражение с любым количеством операндов до фильтрации в grep. Меня что то этот путь в тупик загнал:
function restaurants_filter(restaurants)
{
var active_elements = [
function (e) { return e.car_distribution == 1; },
function (e) { return e.round_the_clock == 1; },
function (e) { return e.wifi == 1; },
function (e) { return e.promo == 1; }
];
var inactive_elements = [
function (e) { return e.car_distribution == 0; },
function (e) { return e.round_the_clock == 0; },
function (e) { return e.wifi == 0; },
function (e) { return e.promo == 0; }
];
var route = $('#route').val();
var wifi = $('#wifi').val();
var schedule = $('#schedule').val();
var promo = $('#promo').val();
var city_id = $('.styled-select').val();
var conditions = [];
// Determine buttons state
var buttons_state = ''+ route +'' + ''+ schedule +'' +''+ wifi +'' + ''+ promo +'' ;
// Accumulate conditions
for ( var i = 0; i < active_elements.length; i++ ) {
if (buttons_state.charAt(i) != '0'){
conditions.push(i);
}
}
var rest = $.grep(restaurants, function (e) {
for ( var i = 0; i < conditions.length; i++ ) {
return active_elements[conditions[i]](e);
}
return rest
}
Примерно вот так нужно реализовать, но возникают сразу 2 вопроса: return в цикле внутри grep - он же применяется последний и оператор && между вызовами функций не поставить. 2-ой - есть ли возможность в JS автоматом поставить логические операторы между всеми элементами массива записав это как единое логическое выражение? к примеру:
function [0](e) && function [1](e) && ....function [n](e)
PS: 2-ой массив в дальнейшем будет использоваться для автоматической генерации дополнительных условий о которых я писал выше(из 1011 - 1000,0001 и т.д.)
Последний раз редактировалось Уханов Сергей, 18.01.2013 в 19:16.
|
|
18.01.2013, 21:37
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
Уханов Сергей,
Вы забодайте функцию создания условных переменных,
тады сократиться тело
типо
var rndCloc,carDistr,promСit,...
function setVario (e) {
rndCloc= (e.round_the_clock == 0);
carDistr =(e.car_distribution == 0 );
promСit = (e.promo == 1 );
//....
}
|
|
18.01.2013, 22:25
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
Или
var Key_active_elements =''+
1*(e.car_distribution == 1)+
1*(e.round_the_clock == 1)+
1*(e.wifi == 1)+
1*(e.promo == 1);
Тогда анализируете на совпадение
if (Key_active_elements=='11011') { //
|
|
19.01.2013, 00:05
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
Сообщение от Deff
|
Вы забодайте функцию
|
в цитатник
Сообщение от Deff
|
Тогда анализируете на совпадение
if (Key_active_elements=='11011') { //
|
проверять биты по маске, не?
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
|
|
19.01.2013, 00:26
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
nerv_,
Там чисто строка, - просто сравнивает с массивом наличных строчных ключей '11011','10001' и т.д
|
|
19.01.2013, 00:44
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
Сообщение от Deff
|
просто сравнивает с массивом наличных строчных ключей '11011','10001' и т.д
|
кстати, надоумил
Вместо switсh или if-else
alert( [ '0000', '0101', '1011', '1111' ].indexOf( '1011' ) );
UPD: Еще вариант
var obj = {
'0000': function() {},
'0101': function() {},
'1011': function() {},
'1111': function() {}
};
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Последний раз редактировалось nerv_, 19.01.2013 в 00:55.
|
|
|
|