107 votes

Access JavaScript property case-insensitively ?

Supposons que j'ai un objet :

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

J'ai besoin d'accéder à une propriété de cet objet de manière dynamique, comme suit :

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

Aucun problème, sauf que prop ne doit pas tenir compte des majuscules et des minuscules au cas où le nom de la propriété serait transmis à la fonction sous la forme de, disons, Foo au lieu de foo .

Alors comment puis-je pointer vers la propriété d'un objet par son nom sans tenir compte de la casse ? Je voudrais éviter d'itérer l'objet entier si possible.

67voto

ShortFuse Points 562

Essayez ça :

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

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

Vous pouvez également fournir la searchKey en minuscules.

Si vous le voulez comme une fonction :

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

Si la clé ne peut pas être trouvée, il retournera undefined comme d'habitude.

Si vous devez prendre en charge des navigateurs plus anciens, vous pouvez alors utiliser filter à la place :

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

Je suggère d'utiliser les polyfills pour Objet.keys() y Array.filter() si vous avez besoin d'un soutien encore plus ancien.


Remarque : Si vous souhaitez également vérifier les clés non énumérables, utilisez la commande Object.getOwnPropertyNames() au lieu de Object.keys() .

Nerdy Note : Cela suppose que votre objet n'a pas de clé. undefined (ex : const foo = {[undefined]: 'bar'}; ). C'est juste bizarre.

29voto

Anoop Points 12862

Comparez toutes les propriétés de obj avec 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;
      }
   }
}

13voto

Matt Goodwin Points 75

Pour cela, je préfère utiliser le prototype plutôt qu'une fonction autonome, simplement pour la facilité d'utilisation et l'expressivité. Je n'aime pas faire passer des objets dans des fonctions si je n'y suis pas obligé.

De plus, bien que la réponse acceptée fonctionne, je voulais une solution plus complète pour l'obtention et le réglage qui se comporterait autant que possible comme la notation native par points ou par crochets.

C'est dans cet esprit que j'ai créé quelques prototypes de fonctions permettant de définir et d'obtenir une propriété d'objet sans tenir compte de la casse. Vous devez vous rappeler d'être TRES responsable lors de l'ajout au prototype de l'objet. Surtout quand on utilise JQuery et d'autres bibliothèques. Object.defineProperty() avec enumerable réglé sur false a été utilisé spécifiquement pour éviter tout conflit avec JQuery. Je n'ai pas non plus pris la peine de nommer les fonctions de manière à indiquer qu'elles sont insensibles à la casse, mais vous pourriez certainement le faire. J'aime les noms courts.

Voici l'attrape-nigaud :

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
});

Voici le passeur :

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
});

Maintenant que nous avons créé ces fonctions, notre code est super propre et concis et fonctionne tout simplement.

Obtention insensible à la casse :

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'

Réglage insensible à la casse :

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'

7voto

Rusty Shackleford Points 1021

Encore une autre variation de celles déjà présentées qui pousse l'itération vers le bas dans l'Underscore/Lodash. findKey fonction :

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

Par exemple :

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

2voto

Claudio Redi Points 34297

Vous pourriez faire cela afin de "normaliser" prop

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X