web-dev-qa-db-ja.com

JavaScriptプロパティに大文字と小文字を区別せずにアクセスしますか?

オブジェクトがあると仮定します。

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

そのように動的にそのオブジェクトのプロパティにアクセスする必要があります。

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

propの代わりにFooのようにプロパティ名が関数に渡される場合、fooで大文字と小文字を区別する必要があることを除いて、問題はありません。

それでは、大文字と小文字を区別せずに名前でオブジェクトのプロパティをポイントするにはどうすればよいですか?可能であれば、オブジェクト全体の反復を避けたいと思います。

53
Matt Cashatt

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;
      }
   }
}
24
Anoop

これを試して:

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

オブジェクトが見つからない場合、通常のように未定義を返します。

古いブラウザをサポートする必要がある場合は、代わりにfilterを使用できます。

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

さらに古いサポートが必要な場合は、 Object.keys() および Array.filter() にポリフィルを使用することをお勧めします。

13
ShortFuse

このため、使いやすさと表現力のためだけに、スタンドアロン関数よりもプロトタイプを使用することを好みます。必要がない場合は、オブジェクトを関数にファンナリングするのが好きではありません。

また、受け入れられた答えは機能しますが、取得と設定の両方について、ネイティブのドット表記またはブラケット表記と可能な限り同じように動作する、より包括的なソリューションが必要でした。

それを念頭に置いて、大文字と小文字を区別せずにオブジェクトプロパティを設定/取得するためのプロトタイプ関数をいくつか作成しました。 Objectプロトタイプに追加するときは、[〜#〜] very [〜#〜]であることを忘れないでください。特に、JQueryおよびその他のライブラリを使用する場合。 enumerableを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'
9
Matt Goodwin

アンダースコア/ロダッシュ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
6

propを「正規化」するためにこれを行うことができます

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

単純にすべて小文字にすることができるのに、なぜそんなに複雑にするのでしょうか。

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

呼び出す:your_object.GetName(your_var.toLowerCase());

1
user2390480

文字列キーを大文字または小文字に変換し、通常のオブジェクトのように動作するトラップを備えたProxyの良い候補のように思えます。これはどちらの表記法でも機能します:ドットまたはブラケ

コードは次のとおりです。

'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"]
1
Enrique Alamo

繰り返しの必要はありません。 propは文字列ではない可能性があるため、オブジェクトがネイティブに実行するものであるため、必要に応じて最初に文字列に強制する必要があります。単純なゲッター関数は次のとおりです。

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;
}
0
RobG

これを行うための非常に簡単なコードを以下に示します。データは次のようなオブジェクトの配列であると仮定します

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"}]
0
prajnavantha

別の簡単な方法:

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

次のように使用します。

var obj = {
  foo:"bar",
  fizz:"buzz"
};
    getVal(obj,"FoO") -> returns "bar"
0
JerryGoyal

大文字と小文字を区別する一致(安価で迅速な)が失敗した場合は、大文字と小文字を区別しない一致(通常はオブジェクトの反復のために費用がかかる)のみを行う必要があります。

あなたが持っていると言う:

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 ;
          } ;
      } 
  } ;
0
dsdsdsdsd