Angenommen, ich habe ein Objekt:
var obj = {
foo:"bar",
fizz:"buzz"
};
Ich muss dynamisch auf eine Eigenschaft dieses Objekts zugreifen, wie folgt:
var objSetter = function(prop,val){
obj[prop] = val;
}
Dort gibt es keine Probleme, außer dass prop
die Groß- und Kleinschreibung nicht berücksichtigt werden muss, wenn der Eigenschaftsname beispielsweise Foo
anstelle von an die Funktion übergeben wird foo
.
Wie kann ich also ohne Rücksicht auf die Groß- und Kleinschreibung namentlich auf die Eigenschaft eines Objekts verweisen? Ich möchte nach Möglichkeit vermeiden, das gesamte Objekt zu wiederholen.
javascript
object
properties
Matt Cashatt
quelle
quelle
obj = {foo: true, Foo: false}
prop
vor der Verwendung in "niedriger " konvertieren .Antworten:
Vergleichen Sie alle Eigenschaften von obj mit 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; } } }
quelle
+ ""
ist? Ist dies nur für die Zeichenfolgenkonvertierung?p
eine Zeichenfolge zu erzwingen . ECMA-262 gibt Objekteigenschaften als Zeichenfolgen an. Jeder Benutzeragent oder Host, der nicht konform war, hätte ernsthafte Probleme. Es besteht auch keine Notwendigkeit fürbreak
, sollten Sie verwendenreturn
.Versuche dies:
var myObject = { "mIxeDCaSEKeY": "value" }; var searchKey = 'mixedCaseKey'; myObject[Object.keys(myObject).find(key => key.toLowerCase() === searchKey.toLowerCase())];
Alternativ können Sie den searchKey bereits in Kleinbuchstaben angeben.
Wenn Sie es als Funktion wollen:
/** * @param {Object} object * @param {string} key * @return {any} value */ function getParameterCaseInsensitive(object, key) { return object[Object.keys(object) .find(k => k.toLowerCase() === key.toLowerCase()) ]; }
Wenn das Objekt nicht gefunden werden kann, wird es wie gewohnt undefiniert zurückgegeben.
Wenn Sie ältere Browser unterstützen müssen, können Sie
filter
stattdessen Folgendes verwenden:function getParameterCaseInsensitive(object, key) { return object[Object.keys(object).filter(function(k) { return k.toLowerCase() === key.toLowerCase(); })[0]]; }
Ich empfehle die Verwendung der Polyfills für Object.keys () und Array.filter (), wenn Sie noch ältere Unterstützung benötigen.
quelle
Aus diesem Grund bevorzuge ich die Verwendung des Prototyps gegenüber einer eigenständigen Funktion, um die Benutzerfreundlichkeit und Ausdruckskraft zu verbessern. Ich mag es einfach nicht, Objekte in Funktionen zu leiten, wenn ich nicht muss.
Während die akzeptierte Antwort funktioniert, wollte ich eine umfassendere Lösung zum Abrufen und Einstellen, die sich so ähnlich wie die native Punktnotation oder Klammernotation wie möglich verhält.
Vor diesem Hintergrund habe ich einige Prototypfunktionen zum Festlegen / Abrufen einer Objekteigenschaft ohne Rücksicht auf die Groß- und Kleinschreibung erstellt. Sie müssen daran denken, beim Hinzufügen zum Objektprototyp SEHR verantwortlich zu sein. Besonders bei Verwendung von JQuery und anderen Bibliotheken. Object.defineProperty () mit der Aufzählung false wurde speziell verwendet, um Konflikte mit JQuery zu vermeiden. Ich habe mich auch nicht darum gekümmert, die Funktionen so zu benennen, dass sie nicht zwischen Groß- und Kleinschreibung unterscheiden, aber Sie könnten es auf jeden Fall. Ich mag kürzere Namen.
Hier ist der 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 });
Hier ist der 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 });
Nachdem wir diese Funktionen erstellt haben, ist unser Code sehr sauber und präzise und funktioniert einfach.
Groß- und Kleinschreibung wird nicht berücksichtigt:
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'
Groß- und Kleinschreibung wird nicht berücksichtigt:
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'
quelle
obj.setProp("GETPROP")
Noch eine Variation der bereits vorgestellten, die die Iteration in die Underscore / Lodash-
findKey
Funktion drückt :var _ = require('underscore'); var getProp = function (obj, name) { var realName = _.findKey(obj, function (value, key) { return key.toLowerCase() === name.toLowerCase(); }); return obj[realName]; };
Zum Beispiel:
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
quelle
underscore
implementiert die Bibliothek dies? Dh ich suche nach einem Weg, der keine lineare Suche der Schlüssel eines Objekts beinhaltetSie könnten dies tun, um "zu normalisieren"
prop
var normalizedProp = prop.toLowerCase(); obj[normalizedProp] = val;
quelle
prop
Kleinbuchstaben umgewandelt wird, aber was ist, wenn ich nicht garantieren kann, dass der tatsächliche Eigenschaftsname nur in Kleinbuchstaben geschrieben wird? Vielleicht fehlt mir etwas?Es ist keine Iteration erforderlich. Da es sich
prop
möglicherweise nicht um eine Zeichenfolge handelt, sollte sie gegebenenfalls zuerst zu einer Zeichenfolge gezwungen werden, da Objekte dies nativ tun. Eine einfache Getter-Funktion ist:function objGetter(prop) { return obj[String(prop).toLowerCase()]; }
Wenn es erforderlich ist, den Zugriff auf eigene Immobilien zu beschränken:
function objGetter(prop) { prop = String(prop).toLowerCase(); if (obj.hasOwnProperty(prop)) { return obj.prop; } }
und ein Setter:
function objSetter(prop, val) { obj[String(prop).toLowerCase()] = val; }
quelle
prop
dass dies an die Funktion objSetter () übergeben wird. Tatsächlich impliziert die Einbeziehung der Funktion objSetter () durch die Fragesteller in erster Linie stark, dass der Autor die Kontrolle über die Erstellung des Objekts hat. Eine Antwort, die besagt, dass die Eigenschaftsnamen auf Kleinbuchstaben normiert werden müssen und dabei Unterstützung bieten, ist eine vernünftige Antwort. Wenn der Autor darüber hinaus mehr benötigt, kann der Autor dies in einem Kommentar oder durch Bearbeiten der Frage klarstellen.Warum sollten wir es so kompliziert machen, wenn wir einfach alles in Kleinbuchstaben schreiben können:
var your_object = { "chickago" : 'hi' , "detroit" : 'word', "atlanta" : 'get r dun', GetName: function (status) { return this[status].name; } };
um es zu nennen:
your_object.GetName(your_var.toLowerCase());
quelle
Es scheint mir ein guter Kandidat für Proxy mit Traps zu sein, um Zeichenfolgenschlüssel entweder in Groß- oder Kleinbuchstaben umzuwandeln und sich wie ein normales Objekt zu verhalten. Dies funktioniert entweder mit Notation: Punkten oder Klammern
Hier ist der 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"]
quelle
const getPropertyNoCase = (obj, prop) => obj[Object.keys(obj).find(key => key.toLowerCase() === prop.toLowerCase() )];
oder
const getPropertyNoCase = (obj, prop) => { const lowerProp = prop.toLowerCase(obj[Object.keys(obj).find(key => key.toLowerCase() === prop.toLowerCase() )]; }
quelle
Hier ist ein sehr einfacher Code, um dies zu tun. Angenommen, Daten sind das Array von Objekten wie
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; }, [])
Ausgabe wird sein
data=[{"a":"bc","b":"nn"}]
quelle
Möglicherweise müssen Sie nur zwischen Groß- und Kleinschreibung unterscheiden (normalerweise teuer aufgrund von Objektiteration), wenn eine Übereinstimmung zwischen Groß- und Kleinschreibung (billig und schnell) fehlschlägt.
Angenommen, Sie haben:
var your_object = { "Chicago" : 'hi' , "deTroiT" : 'word' , "atlanta" : 'get r dun' } ;
Und Sie haben aus irgendeinem Grund den Wert
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 ; } ; } } ;
quelle
Ein anderer einfacher Weg:
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; }
Verwenden Sie es so:
var obj = { foo:"bar", fizz:"buzz" }; getVal(obj,"FoO") -> returns "bar"
quelle
Diese Antwort erfordert ES6.
const x = {'X-Total-Count':10}; console.log(x[Object.keys(x).reduce(key=>{return key.match(/x-total-count/i)})]);
quelle
Hier ist eine nette rekursive Funktion, mit der Sie ein Javascript-Objekt ohne Berücksichtigung der Groß- und Kleinschreibung durchlaufen können:
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]
quelle