Подтвердить что ты не робот

Получите доступ к свойствам JavaScript без учета регистра?

Спасибо, что посмотрели.

Предположим, у меня есть объект:

var obj = {
  foo:"bar",
  fizz:"buzz"
};

Мне нужно получить доступ к свойству этого объекта динамически следующим образом:

var objSetter = function(prop,val){
  obj[prop] = val;
}

Там нет проблем, кроме того, что prop должен быть нечувствительным к регистру, если имя свойства передается в функцию как, скажем, Foo вместо Foo.

Итак, как я могу указать свойство объекта по имени без учета случая? Я хотел бы избежать итерации всего объекта, если это возможно.

Спасибо!

4b9b3361

Ответ 1

Сравните все свойства obj с prop.

var objSetter = function(prop,val){
  prop = (prop + "").toLowerCase();
  for(var p in obj){
     if(obj.hasOwnProperty(p) && prop == (p+ "").toLowerCase()){
           obj[p] = val;
           break;
      }
   }
}

Ответ 2

Вы можете сделать это, чтобы "нормализовать" prop

 var normalizedProp = prop.toLowerCase();
 obj[normalizedProp] = val;

Ответ 3

Для этого я предпочитаю использовать прототип над автономной функцией только для удобства использования и выразительности. Мне просто не нравится вставлять объекты в функции, если мне это не нужно.

Кроме того, в то время как принятый ответ работает, я хотел получить более полное решение как для получения, так и для установки, которое будет вести себя так же, как обозначение нативной точки или обозначение скобки, насколько это возможно.

С учетом этого, я создал пару прототипов функций для установки/получения свойства объекта без учета случая. При добавлении в прототип объекта вы должны помнить, что ОЧЕНЬ. Особенно при использовании JQuery и других библиотек. Object.defineProperty() с перечислимым набором в false использовался специально, чтобы избежать конфликта с JQuery. Я также не стал называть функции тем, что указывает на то, что они не чувствительны к регистру, но вы, безусловно, могли бы. Мне нравятся короткие имена.

Здесь получатель:

Object.defineProperty(Object.prototype, "getProp", {
    value: function (prop) {
        var key,self = this;
        for (key in self) {
            if (key.toLowerCase() == prop.toLowerCase()) {
                return self[key];
            }
        }
    },
    //this keeps jquery happy
    enumerable: false
});

Здесь сеттер:

Object.defineProperty(Object.prototype, "setProp", {
    value: function (prop, val) {
        var key,self = this;
        var found = false;
        if (Object.keys(self).length > 0) {
            for (key in self) {
                if (key.toLowerCase() == prop.toLowerCase()) {
                    //set existing property
                    found = true;                        
                    self[key] = val;
                    break;
                }
            }
        }

        if (!found) {
            //if the property was not found, create it
            self[prop] = val;
        }  

        return val;
    },
    //this keeps jquery happy
    enumerable: false
});

Теперь, когда мы создали эти функции, наш код является супер чистым и кратким и просто работает.

Нечувствительность к регистру:

var obj = {foo: 'bar', camelCase: 'humpy'}

obj.getProp("FOO");          //returns 'bar'
obj.getProp("fOO");          //returns 'bar'
obj.getProp("CAMELCASE");    //returns 'humpy' 
obj.getProp("CamelCase");    //returns 'humpy'

Нечувствительность к регистру:

var obj = {foo: 'bar', camelCase: 'humpy'}

obj.setProp('CAmelCasE', 'super humpy');     //sets prop 'camelCase' to 'super humpy'
obj.setProp('newProp', 'newval');      //creates prop 'newProp' and sets val to 'newval'  
obj.setProp('NewProp', 'anotherval');  //sets prop 'newProp' to 'anotherval'

Ответ 4

Еще одна вариация на уже представленные, которая толкает итерацию вниз в функцию Underscore/Lodash findKey:

var _ = require('underscore');
var getProp = function (obj, name) {
    var realName = _.findKey(obj, function (value, key) {
        return key.toLowerCase() === name.toLowerCase();
    });
    return obj[realName];
};

Например:

var obj = { aa: 1, bB: 2, Cc: 3, DD: 4 };
getProp(obj, 'aa'); // 1
getProp(obj, 'AA'); // 1
getProp(obj, 'bb'); // 2
getProp(obj, 'BB'); // 2
getProp(obj, 'cc'); // 3
getProp(obj, 'CC'); // 3
getProp(obj, 'dd'); // 4
getProp(obj, 'DD'); // 4
getProp(obj, 'EE'); // undefined

Ответ 5

зачем нам это делать, что сложно, когда мы просто можем сделать все в нижнем регистре:

    var your_object = { 
"chickago" : 'hi' ,
 "detroit" : 'word', 
 "atlanta" : 'get r dun',     
GetName: function (status) {
        return this[status].name;
    } };

, чтобы называть его: your_object.GetName(your_var.toLowerCase());

Ответ 6

Нет никакой итерации. Поскольку prop может не быть строкой, ее следует принуждать к строке сначала, когда это необходимо, так как те, что объекты изначально. Простая функция getter:

function objGetter(prop) {
  return obj[String(prop).toLowerCase()];
}

Если существует требование переустановить доступ к собственным свойствам:

function objGetter(prop) {
  prop = String(prop).toLowerCase();

  if (obj.hasOwnProperty(prop)) {
    return obj.prop;
  }
}

и сеттер:

function objSetter(prop, val) {
  obj[String(prop).toLowerCase()] = val;
}

Ответ 7

Вот очень простой код для этого Предполагая, что данные представляют собой массив объектов типа

data=[{"A":"bc","B":"nn"}]

var data=data.reduce(function(prev, curr) {
    var cc = curr; // current value
    var K = Object.keys(cc); // get all keys
    var n = {};
    for (var i = 0; i < K.length; i++) {
        var key = K[i];//get hte key

        n[key.toLowerCase()] = cc[key] // convert to lowercase and assign 
    }
    prev.push(n) // push to array
    return prev;
}, [])

Выход будет

data=[{"a":"bc","b":"nn"}]

Ответ 8

Вам может потребоваться выполнить нечувствительность к регистру (обычно дорогостоящую из-за итерации объекта), если совпадение с учетом регистра (дешевое и быстрое) терпит неудачу.

Скажите, что у вас есть:

var your_object = { "Chicago" : 'hi' , "deTroiT" : 'word' , "atlanta" : 'get r dun' } ;

И по какой-то причине у вас есть значение the_value, Detroit:

if( your_object.hasOwnProperty( the_value ) ) 
  { 
    // do what you need to do here
  } 
else  
  { // since the case-sensitive match did not succeed, 
    //   ... Now try a the more-expensive case-insensitive matching

    for( let lvs_prop in your_object ) 
      { if( the_value.toLowerCase()  == lvs_prop.toLowerCase() ) 
          { 

            // do what you need to do here

            break ;
          } ;
      } 
  } ;

Ответ 9

Попробуйте следующее:

var myObject = { "mIxeDCaSEKeY": "value" };

var searchKey = 'mixedCaseKey';
myObject[Object.keys(myObject).find(key => key.toLowerCase() === searchKey.toLowerCase())];

Вы можете альтернативно уже предоставить searchKey в нижнем регистре.

Если вы хотите его как функцию:

/**
  * @param {Object} object
  * @param {string} key
  * @return {any} value
 */
function getParameterCaseInsensitive(object, key) {
  return object[Object.keys(object)
    .find(k => k.toLowerCase() === key.toLowerCase())
  ];
}

Если объект не найден, он вернет undefined, как обычно.

Если вам нужно поддерживать старые браузеры, вы можете вместо этого использовать filter:

function getParameterCaseInsensitive(object, key) {
  return object[Object.keys(object).filter(function(k) {
    return k.toLowerCase() === key.toLowerCase();
  })[0]];
}

Я предлагаю использовать полисы для Object.keys() и Array.filter(), если вам нужна более старая поддержка.