Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 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.
Ответить с цитированием
  #2 (permalink)  
Старый 17.01.2013, 16:04
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Сообщение от Уханов Сергей
Пожалуйста поделитесь своими соображениями на счет оптимального способа построения сложного условия. Что то не хочется делать через 0000,1111,0101,1000 и так далее....
1. Комплексные зависимости от них никуда не деться, а побитовые и межбитовые(двух и трёх) выносить в отдельные функции

Последний раз редактировалось Deff, 18.01.2013 в 07:38.
Ответить с цитированием
  #3 (permalink)  
Старый 18.01.2013, 07:27
Новичок на форуме
Отправить личное сообщение для Уханов Сергей Посмотреть профиль Найти все сообщения от Уханов Сергей
 
Регистрация: 17.01.2013
Сообщений: 5

Спасибо за ответ! Была конечно мысль накопить строчку по фильтрам и выполнить в eval, но народ не советует. Очень жаль...
Ответить с цитированием
  #4 (permalink)  
Старый 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));
Ответить с цитированием
  #5 (permalink)  
Старый 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.
Ответить с цитированием
  #6 (permalink)  
Старый 18.01.2013, 21:37
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 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 );
//....
}
Ответить с цитированием
  #7 (permalink)  
Старый 18.01.2013, 22:25
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 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') { //
Ответить с цитированием
  #8 (permalink)  
Старый 19.01.2013, 00:05
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Сообщение от Deff
Вы забодайте функцию
в цитатник

Сообщение от Deff
Тогда анализируете на совпадение
if (Key_active_elements=='11011') { //
проверять биты по маске, не?
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #9 (permalink)  
Старый 19.01.2013, 00:26
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

nerv_,
Там чисто строка, - просто сравнивает с массивом наличных строчных ключей '11011','10001' и т.д
Ответить с цитированием
  #10 (permalink)  
Старый 19.01.2013, 00:44
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 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.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск