假设我有一个对象:
var obj = {
foo:"bar",
fizz:"buzz"
};
我需要像这样动态地访问该对象的属性:
var objSetter = function(prop,val){
obj[prop] = val;
}
那里没有任何问题,除了prop
万一属性名称以Foo
代替的形式传递给函数时,它不需要区分大小写foo
。
那么,如何不区分大小写地通过名称指向对象的属性呢?如果可能,我想避免迭代整个对象。
假设我有一个对象:
var obj = {
foo:"bar",
fizz:"buzz"
};
我需要像这样动态地访问该对象的属性:
var objSetter = function(prop,val){
obj[prop] = val;
}
那里没有任何问题,除了prop
万一属性名称以Foo
代替的形式传递给函数时,它不需要区分大小写foo
。
那么,如何不区分大小写地通过名称指向对象的属性呢?如果可能,我想避免迭代整个对象。
prop
在使用前将其转换为小写。
Answers:
将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;
}
}
}
+ ""
是做什么用的吗?这仅用于字符串转换吗?
p
使用字符串,ECMA-262将对象属性指定为字符串,任何不符合要求的用户代理或主机都会遇到严重问题。也没有必要break
,应该使用return
。
试试这个:
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()使用polyfills。
为此,我更喜欢使用原型而不是独立功能,只是为了易于使用和表达。我只是不喜欢将对象集中到函数中。
另外,虽然可接受的答案有效,但我希望获得和设置都更全面的解决方案,使其表现得尽可能像本机点表示法或方括号表示法。
考虑到这一点,我创建了几个原型函数,用于在不考虑大小写的情况下设置/获取对象属性。添加到对象原型时,您必须记住要非常负责。特别是在使用JQuery和其他库时。可枚举设置为false的Object.defineProperty()专门用于避免与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'
obj.setProp("GETPROP")
对已经介绍的内容的另一种变化形式将迭代推入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];
};
例如:
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
underscore
图书馆如何实现呢?即,我正在寻找一种不涉及某些对象键的线性搜索的方法
您可以执行此操作以“规范化” prop
var normalizedProp = prop.toLowerCase();
obj[normalizedProp] = val;
prop
为小写字母,但是如果我不能保证实际的属性名称全部为小写字母怎么办?也许我缺少什么?
不需要任何迭代。由于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;
}
prop
传递给objSetter()函数的情况。实际上,质疑者首先将objSetter()函数包含进来就强烈暗示了作者可以控制对象的创建。指出属性名称必须规范化为小写并提供帮助的答案是一个合理的答案。如果作者还有其他需求,则可以在评论中或通过编辑问题进行澄清。
在我看来,代理服务器是一个不错的选择,可以使用陷阱将字符串键转换为大写或小写,并且表现得像普通对象。这适用于两种符号:点或球拍
这是代码:
'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"]
const getPropertyNoCase = (obj, prop) => obj[Object.keys(obj).find(key => key.toLowerCase() === prop.toLowerCase() )];
要么
const getPropertyNoCase = (obj, prop) => {
const lowerProp = prop.toLowerCase(obj[Object.keys(obj).find(key => key.toLowerCase() === prop.toLowerCase() )];
}
这是执行此操作的非常简单的代码,假设数据是对象数组,例如
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"}]
如果区分大小写的匹配(便宜又快速)失败了,您可能只需要进行不区分大小写的匹配(由于对象迭代而通常比较昂贵)。
说您有:
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 ;
} ;
}
} ;
这是一个很好的递归函数,它允许您以不区分大小写的方式遍历javascript对象:
let testObject = {'a': {'B': {'cC': [1,2,3]}}}
let testSeq = ['a','b','cc']
function keySequence(o, kseq) {
if(kseq.length==0){ return o; }
let validKeys = Object.keys(o).filter(k=>k.toLowerCase()==kseq[0].toLowerCase());
if(validKeys.length==0) { return `Incorrect Key: ${kseq[0]}` }
return keySequence(o[validKeys[0]], kseq.slice(1))
}
keySequence(testObject, testSeq); //returns [1,2,3]
obj = {foo: true, Foo: false}