不区分大小写访问 JavaScript 属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12484386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Access JavaScript property case-insensitively?
提问by Matt Cashatt
Assume I have an object:
假设我有一个对象:
var obj = {
foo:"bar",
fizz:"buzz"
};
I need to access a property of that object dynamically like so:
我需要像这样动态访问该对象的属性:
var objSetter = function(prop,val){
obj[prop] = val;
}
No problems there, except for that prop
needs to be case insensitive in case the property name is passed into the function as, say, Foo
instead of foo
.
那里没有问题,除了prop
需要不区分大小写,以防将属性名称传递给函数,例如,Foo
而不是foo
.
So how can I point to an object's property by name without regard to case? I would like to avoid iterating the entire object if possible.
那么如何在不考虑大小写的情况下按名称指向对象的属性呢?如果可能,我想避免迭代整个对象。
采纳答案by Anoop
Compare all the properties of obj with prop.
将 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;
}
}
}
回答by ShortFuse
Try this:
尝试这个:
var myObject = { "mIxeDCaSEKeY": "value" };
var searchKey = 'mixedCaseKey';
myObject[Object.keys(myObject).find(key => key.toLowerCase() === searchKey.toLowerCase())];
You can alternatively already provide the searchKey in lowercase.
您也可以提供小写的 searchKey。
If you want it as a function:
如果你想把它作为一个函数:
/**
* @param {Object} object
* @param {string} key
* @return {any} value
*/
function getParameterCaseInsensitive(object, key) {
return object[Object.keys(object)
.find(k => k.toLowerCase() === key.toLowerCase())
];
}
If the object can't be found, then it'll return undefined, just like normal.
如果找不到对象,那么它会像平常一样返回 undefined。
If you need to support older browsers, then you can use filter
instead:
如果您需要支持较旧的浏览器,则可以filter
改用:
function getParameterCaseInsensitive(object, key) {
return object[Object.keys(object).filter(function(k) {
return k.toLowerCase() === key.toLowerCase();
})[0]];
}
I suggest using the polyfills for Object.keys()and Array.filter()if you need even older support.
如果您需要更旧的支持,我建议使用用于Object.keys()和Array.filter() 的 polyfill。
回答by Matt Goodwin
For this, I prefer using the prototype over a standalone function just for ease of use and expressiveness. I just don't like funneling objects into functions if I don't have to.
为此,我更喜欢使用原型而不是独立函数,只是为了便于使用和表达。如果我不需要,我只是不喜欢将对象汇集到函数中。
Also, while the accepted answer works, I wanted a more comprehensive solution for both getting and setting that would behave as much like the native dot notation or bracket notation as possible.
此外,虽然接受的答案有效,但我想要一个更全面的获取和设置解决方案,其行为尽可能像本地点表示法或括号表示法。
With that in mind, I created a couple prototype functions for setting/getting an object property without regard to case. You have to remember to be VERYresponsible when adding to the Object prototype. Especially when using JQuery and other libraries. Object.defineProperty() with enumerable set to false was used specifically to avoid conflict with JQuery. I also didn't bother naming the functions anything that indicates they are case-insensitive, but you certainly could. I like shorter names.
考虑到这一点,我创建了几个原型函数来设置/获取对象属性而不考虑大小写。在添加到对象原型时,您必须记住要非常负责。特别是在使用 JQuery 和其他库时。将 enumerable 设置为 false 的 Object.defineProperty() 专门用于避免与 JQuery 发生冲突。我也没有费心为函数命名任何表明它们不区分大小写的东西,但你当然可以。我喜欢较短的名字。
Here's the getter:
这是吸气剂:
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
});
Here's the setter:
这是二传手:
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
});
Now that we've created those functions, our code is super clean and concise and just works.
现在我们已经创建了这些函数,我们的代码非常干净简洁并且可以正常工作。
Case-insensitive getting:
不区分大小写的获取:
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'
Case-insensitive setting:
不区分大小写的设置:
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'
回答by Rusty Shackleford
Yet another variation on those already presented which pushes the iteration down into the Underscore/Lodash findKey
function:
已经提出的另一种变体将迭代推入 Underscore/LodashfindKey
函数:
var _ = require('underscore');
var getProp = function (obj, name) {
var realName = _.findKey(obj, function (value, key) {
return key.toLowerCase() === name.toLowerCase();
});
return obj[realName];
};
For example:
例如:
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
回答by Claudio Redi
You could do this in order to "normalize" prop
您可以这样做以“正常化” prop
var normalizedProp = prop.toLowerCase();
obj[normalizedProp] = val;
回答by KaiOsmon
why would we do it that complicated when we simply can make it all lower case:
当我们可以简单地将其全部设为小写时,为什么我们要这样做那么复杂:
var your_object = {
"chickago" : 'hi' ,
"detroit" : 'word',
"atlanta" : 'get r dun',
GetName: function (status) {
return this[status].name;
} };
to call it:your_object.GetName(your_var.toLowerCase());
调用它:your_object.GetName(your_var.toLowerCase());
回答by Enrique Alamo
It seems to me like a good candidate for Proxy with traps to convert string keys to either upper case or lower case and behaving like a regular object. This works with either notation: dots or braquets
在我看来,它是带有陷阱的 Proxy 的一个很好的候选者,可以将字符串键转换为大写或小写,并且表现得像一个普通对象。这适用于任何一种符号:点或括号
Here is the code:
这是代码:
'use strict';
function noCasePropObj(obj)
{
var handler =
{
get: function(target, key)
{
//console.log("key: " + key.toString());
if (typeof key == "string")
{
var uKey = key.toUpperCase();
if ((key != uKey) && (key in target))
return target[key];
return target[uKey];
}
return target[key];
},
set: function(target, key, value)
{
if (typeof key == "string")
{
var uKey = key.toUpperCase();
if ((key != uKey) && (key in target))
target[key] = value;
target[uKey] = value;
}
else
target[key] = value;
},
deleteProperty: function(target, key)
{
if (typeof key == "string")
{
var uKey = key.toUpperCase();
if ((key != uKey) && (key in target))
delete target[key];
if (uKey in target)
delete target[uKey];
}
else
delete target[key];
},
};
function checkAtomic(value)
{
if (typeof value == "object")
return new noCasePropObj(value); // recursive call only for Objects
return value;
}
var newObj;
if (typeof obj == "object")
{
newObj = new Proxy({}, handler);
// traverse the Original object converting string keys to upper case
for (var key in obj)
{
if (typeof key == "string")
{
var objKey = key.toUpperCase();
if (!(key in newObj))
newObj[objKey] = checkAtomic(obj[key]);
}
}
}
else if (Array.isArray(obj))
{
// in an array of objects convert to upper case string keys within each row
newObj = new Array();
for (var i = 0; i < obj.length; i++)
newObj[i] = checkAtomic(obj[i]);
}
return newObj; // object with upper cased keys
}
// Use Sample:
var b = {Name: "Enrique", last: "Alamo", AdDrEsS: {Street: "1233 Main Street", CITY: "Somewhere", zip: 33333}};
console.log("Original: " + JSON.stringify(b)); // Original: {"Name":"Enrique","last":"Alamo","AdDrEsS":{"Street":"1233 Main Street","CITY":"Somewhere","zip":33333}}
var t = noCasePropObj(b);
console.log(JSON.stringify(t)); // {"NAME":"Enrique","LAST":"Alamo","ADDRESS":{"STREET":"1233 Main Street","CITY":"Somewhere","ZIP":33333}}
console.log('.NaMe:' + t.NaMe); // .NaMe:Enrique
console.log('["naME"]:' + t["naME"]); // ["naME"]:Enrique
console.log('.ADDreSS["CitY"]:' + t.ADDreSS["CitY"]); // .ADDreSS["CitY"]:Somewhere
console.log('check:' + JSON.stringify(Object.getOwnPropertyNames(t))); // check:["NAME","LAST","ADDRESS"]
console.log('check2:' + JSON.stringify(Object.getOwnPropertyNames(t['AddresS']))); // check2:["STREET","CITY","ZIP"]
回答by nilloc
This answer requires ES6.
这个答案需要 ES6。
const x = {'X-Total-Count':10};
console.log(x[Object.keys(x).reduce(key=>{return key.match(/x-total-count/i)})]);
回答by Yaron Pdut
const getPropertyNoCase = (obj, prop) => obj[Object.keys(obj).find(key => key.toLowerCase() === prop.toLowerCase() )];
or
或者
const getPropertyNoCase = (obj, prop) => {
const lowerProp = prop.toLowerCase(obj[Object.keys(obj).find(key => key.toLowerCase() === prop.toLowerCase() )];
}
回答by JerryGoyal
Another simple way:
另一种简单的方法:
function getVal(obj, prop){
var val;
prop = (prop + "").toLowerCase();
for(var p in obj){
if(obj.hasOwnProperty(p) && prop == (p+ "").toLowerCase()){
val = obj[p]
break;
}
}
return val;
}
Use it like this:
像这样使用它:
var obj = {
foo:"bar",
fizz:"buzz"
};
getVal(obj,"FoO") -> returns "bar"