вложенные литеральные объекты и фильтрация по нижнему регистру

У меня есть страница, на которой я получаю значения строки запроса, например:

?Target=Customers&Sector=Private

он также может принимать те же значения, что и строчные буквы, в зависимости от пользователя.

У меня есть следующий объект на моей странице:

var settings = {
    Target = { T1: "Customer", T2: "Partner", T3 : "Other"  }, 
    Sector = { S1 : "Private", S2 : "Public", S3 : "Other" } 
}

Мне нужно взять строку запроса и получить имена свойств, такие как T1, T2, S1 и т. д., поскольку я хочу отправить их куда-то еще.

Мой код для этого выглядит так:

//Here I am converting all the main settings properties to small letters, in csae the user passes "customer"
 var settingskey, keys = Object.keys(settings);
    var n = keys.length; 
    var newSettings = {};
    while(n--){
        settingskey = keys[n];
        newSettings[settingskey.toLowerCase()] = settings[settingskey];
    }

//Now I have my new object
    var resultArray = "";  // This is the final array where I will fill the values like T1 S1
    //get query string
    var url = window.location.search;
    //get rid of ? character
    url = url.substring(1);
    //separate each key, value pairs
    var keyvalueArray = url.split('&');
    //loop through all key value pairs
    keyvalueArray.forEach(function(keyvalue){
        //get key, ex: Target
        var key = keyvalue.split('=')[0];
        //get value, ex: Customer
        var val = keyvalue.split('=')[1];
        console.log(key);
        console.log(val);

        for(p in newSettings){
            if(p == key.toLowerCase())
            {
                var element = {};
                element =  newSettings[key.toLowerCase()];   
                var elementValue, elementValues = Object.values(element);
                var newElement = {};
                var n = elementValues.length;
                newElement.keys = element.keys; 
                while(n--){

                    elementValue = elementValues[n];
                    newElement[n] = elementValue.toLowerCase();
                }     
                for(var prop in newElement){
                    if(element[prop] == val){
                        classArray+= "." + prop + ", ";
                    }
                }


          break;
        }
    }
});

resultArray = resultArray.substring(0, resultArray.lastIndexOf(',')).trim();

По сути, я получаю имена свойств в первый раз, например, Target и сектор, преобразовываю их в маленькие буквы и создаю новый объект. Затем я «пытаюсь» создать новый объект для каждого с новым «значением», поэтому вместо «Клиент» я хочу «Клиент».

Есть ли простой и эффективный способ сравнить строку запроса с вложенными литеральными значениями/ключами объекта, написанными маленькими буквами? что, если у меня есть еще 3-4 вложенных уровня, это означает больше вложенных циклов.

Я хочу, когда я перехожу ?target=customer§or=private

вернуть: "T1 S1" в виде строки

Если я прохожу: ?Target=cuSTomer§or=oThEr

вернуть: "T1 S3" в виде строки

Есть идеи?


person Jacky    schedule 05.12.2016    source источник
comment
Пожалуйста, предоставьте четко ожидаемый результат, основанный на примере.   -  person trincot    schedule 06.12.2016
comment
Нет смысла перечислять объект для поиска ключа, когда можно просто найти свойство? Отбросьте for(p in newSettings) if(p == key.toLowerCase()) и замените его максимум на if (key.toLowerCase() in newSettings).   -  person Bergi    schedule 06.12.2016
comment
@trincot Я внес правку в конец поста, пожалуйста, проверьте ее.   -  person Jacky    schedule 06.12.2016
comment
@Bergi, а как насчет вложенного объекта, мне нужно сопоставить элементы на основе значений   -  person Jacky    schedule 06.12.2016
comment
@Jacky Вам не повезло (если вы не инвертировали все объекты раньше), хотя цикл while и newElement все же не нужны. Просто for (var p in element) if (element[p].toLowerCase() == val) results.push(p.toLowerCase())   -  person Bergi    schedule 06.12.2016
comment
Разве нет способа получить объект, перебрать все свойства/значения, преобразовать их в нижний регистр?   -  person Jacky    schedule 06.12.2016


Ответы (1)


Вы можете поменять местами ключ/значение на самом глубоком уровне ваших настроек, чтобы вы могли напрямую найти «T1», когда заданы «цель» и «клиент». Таким образом, замененный объект настроек будет выглядеть так:

var settings = {
    target: { customer: "T1", partner: "T2", other: "T3"  }, 
    sector: { private: "S1", public: "S2", other: "S3" } 
}

Вот функция, которая делает этот обмен, а затем возвращает массив сделанных переводов, который вы можете превратить в строку, разделенную пробелами:

function getCodes(url, settings) {
    var swapped = Object.keys(settings).reduce( function (obj, key) {
        obj[key.toLowerCase()] = Object.keys(settings[key]).reduce ( function (obj2, key2) {
            obj2[settings[key][key2].toLowerCase()] = key2;
            return obj2;
         }, {} ); 
         return obj;
    }, {} );
    return url.toLowerCase().split(/[?&#]/).slice(1).map( function (arg) {
        var parts = arg.split('=');
        return swapped[parts[0].toLowerCase()][parts[1].toLowerCase()];
    } );
}

var url= 'http://www.example.com?Target=Customer&Sector=Private';

var settings = {
    Target: { T1: "Customer", T2: "Partner", T3 : "Other"  }, 
    Sector: { S1 : "Private", S2 : "Public", S3 : "Other" } 
}

var result = getCodes(url, settings).join(' ');

console.log(result);

person trincot    schedule 05.12.2016
comment
Это потрясающе..! Но поддерживается ли он в старых браузерах? Это ECMAscript 2015, верно? - person Jacky; 06.12.2016
comment
Я попробовал это в IE11 и получил ошибку в этой строке: let swapped = Object.keys(settings).reduce( (obj, key) =› { ... он сказал: Expected ; - person Jacky; 06.12.2016
comment
Действительно, это ES6 (EcmaScript2015). Я предположил, что у вас есть поддержка для этого, поскольку вы даже использовали Object.values в своем собственном коде, который IE также не поддерживает. В любом случае, я обновил свой ответ, чтобы он теперь был совместим с ES5. - person trincot; 06.12.2016
comment
благодарю вас. Как вы узнали, что Object.values ​​не поддерживается в IE? Как я узнаю о таких случаях, когда я делаю свою разработку? - person Jacky; 06.12.2016
comment
Вы можете найти его, например, в MDN часто есть раздел Совместимость с браузером, например здесь. Кстати, если этот ответ соответствует вашим потребностям, отметьте его как принятый. - person trincot; 06.12.2016
comment
Большое спасибо за ваше руководство - person Jacky; 07.12.2016
comment
У меня возникает эта ошибка в IE при выполнении строки var [key, val] = arg.split('='); .. У меня: Ожидаемая ошибка идентификатора. Любое решение для этого? у меня ИЕ 10 - person Jacky; 22.12.2016
comment
IE10 устарел, даже IE11 мало что поддерживает EcmaScript2015. В любом случае, я обновил код для работы в IE10, надеюсь. - person trincot; 22.12.2016