Оптимальный способ построения сложного условия с множеством параметров
Всем привет, столкнулся со следующей задачей в которой мне нужен совет:
Существует 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 и так далее.... |
Цитата:
|
Спасибо за ответ! Была конечно мысль накопить строчку по фильтрам и выполнить в eval, но народ не советует. Очень жаль...
|
Спасибо за путеводную нить, гражданин-трансгуманист:)
Буду пытаться реализовать по вашей концепции, нужно будет только додумать некоторые моменты: например, при сочетании фильтров 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));
|
Нда, действительно проблема.... Составные условия не могу использовать при таком подходе. Как думаете есть возможность построить условное выражение с любым количеством операндов до фильтрации в 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 и т.д.) |
Уханов Сергей,
Вы забодайте функцию создания условных переменных, тады сократиться тело типо
var rndCloc,carDistr,promСit,...
function setVario (e) {
rndCloc= (e.round_the_clock == 0);
carDistr =(e.car_distribution == 0 );
promСit = (e.promo == 1 );
//....
}
|
Или
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') { // |
Цитата:
Цитата:
|
nerv_,
Там чисто строка, - просто сравнивает с массивом наличных строчных ключей '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_,
Второй больше нравицо - более кроссбраузерно! |
Цитата:
1011 || 1000 || 0001 || 0010 || 1001 || 1010 || 0011вот именно это и выносит мозг. Но в любом случае, огромное всем спасибо, что не остаетесь безучастными! |
Цитата:
alert('1011'.search(/..11$/)!=-1)
Допустим наличие первых трёх 101
alert('1011'.search(/101.$/)!=-1)
Допустим наличие 1X1X
alert('1011'.search(/1.1.$/)!=-1)
|
| Часовой пояс GMT +3, время: 12:02. |