【问题标题】:How to get a key in a JavaScript object by its value?如何通过值获取 JavaScript 对象中的键?
【发布时间】:2012-04-12 00:57:25
【问题描述】:

我有一个非常简单的 JavaScript 对象,我将其用作关联数组。是否有一个简单的函数可以让我获取值的键,还是我必须迭代对象并手动找到它?

【问题讨论】:

  • 没有这样的标准函数可以做到这一点。如果映射确实是双向的,那么构造一个“翻转”映射并为其编制索引是微不足道的。否则,一个简单的属性迭代器(可能带有一个 hasOwnProperty gaurd)和一个隐藏在函数中的提前返回就很好......
  • 如果一个对象被多个键引用,这将如何工作? var o = []; var map = {first: o, second: o}find_key(o) 会返回什么?
  • 没关系 ;) 我只打算将它用于具有唯一键值对的数组。
  • 我做了一个没有迭代的版本stackoverflow.com/a/36705765/696535。在 jsfiddle 中测试所有提出的解决方案会很有趣

标签: javascript object


【解决方案1】:

我知道我迟到了,但您对我今天制作的这个 EMCMAScript 2017 解决方案有何看法?它处理多个匹配,因为如果两个键具有相同的值会发生什么?这就是我创建这个小 sn-p 的原因。

当有一个匹配时,它只返回一个字符串,当有多个匹配时,它返回一个数组。

let object = { nine_eleven_was_a_inside_job: false, javascript_isnt_useful: false }

// Complex, dirty but useful. Handle mutiple matchs which is the main difficulty.
Object.prototype.getKeyByValue = function (val) {
  
  let array = [];
  let array2 = [];
  
  // Get all the key in the object.
  for(const [key] of Object.entries(this)) {
    if (this[key] == val) {
      // Putting them in the 1st array.
      array.push(key)
    }
  }
  
  // List all the value of the 1st array.
  for(key of array) {
    // "If one of the key in the array is equal to the value passed in the function (val), it means that 'val' correspond to it."
    if(this[key] == val) {
      // Push all the matchs. 
      array2.push(key);
    }
  }
  
  // Check the lenght of the array.
  if (array2.length < 2) {
    // If it's under 2, only return the single value but not in the array. 
    return array2[0];
  } else {
    // If it's above or equal to 2, return the entire array.
    return array2; 
  }
}

/*

Basic way to do it wich doesn't handle multiple matchs.

let getKeyByValue = function (object, val) {
  for(const [key, content] of Object.entries(object)) {
    if (object[key] === val) {
      return key
    }
  }
}
*/

console.log(object.getKeyByValue(false))

【讨论】:

    【解决方案2】:

    如果您有一个具有 数组值 的对象。这是一个很好的例子。让我们假设您想根据您拥有的文件的扩展名显示一个图标。具有相同图标的所有扩展都在相同的对象值下。

    注意:将这里的 case 包裹在一个对象中比使用很多 case 进行 switch 更好。

    检查下面的代码 sn-p(用 es6 编写),看看我们如何返回特定扩展的特定键。

    我从这个git repo得到了扩展列表

    // Oject that contains different icons for different extentions
    const icons = {
        "music": ["mp3", "m4a", "ogg", "acc", "flac","m3u", "wav"],
        "video": ["mp4","webm", "mkv", "avi", "mov", "m4v", "mpeg"],
        "image": ["jpg", "gif", "png", "jpeg", "tif", "psd", "raw", "ico"],
        "archives": ["zip", "rar", "tar", "dmg", "jar"],
        "3d-files": ["3ds", "dwg", "obj", "dae", "skp", "fbx"],
        "text": ["doc", "rtf", "txt", "odt", "tex"],
        "vector-graphics":["ai", "svg"],
        "pdf": ["pdf"],
        "data": ["xml", "csv", "xls"]
    }
    
    const get_icon_Key =( icons_object,file_extention) => {
       // For each key we chack if the value is contained in the list of values
       let key = Object.keys(icons_object).find(
        k=> icons[k].find(
                // At this leve we check if the extention exist in the array of the specific object value ie. 'music', 'video' ...
                icons_ext => icons_ext === file_extention)  
                // if we find it means this is the key we are looking for
                ? true: false);
        return key
    }
    
    console.log(`The icon of for mp3 extention is: => ${get_icon_Key(icons,"mp3")}`)
    console.log(`The icon of for mp4 extention is: => ${get_icon_Key(icons,"mp4")}`)

    【讨论】:

      【解决方案3】:

      这对我来说可以获取对象的键/值。

      let obj = {
              'key1': 'value1',
              'key2': 'value2',
              'key3': 'value3',
              'key4': 'value4'
          }
          Object.keys(obj).map(function(k){ 
          console.log("key with value: "+k +" = "+obj[k])    
          
          })
          

      【讨论】:

        【解决方案4】:

        ES6+ One Liners

        let key = Object.keys(obj).find(k=>obj[k]===value);
        

        返回所有带有值的键:

        let keys = Object.keys(obj).filter(k=>obj[k]===value);
        

        【讨论】:

          【解决方案5】:

          没有看到以下内容:

          const obj = {
            id: 1,
            name: 'Den'
          };
          
          function getKeyByValue(obj, value) {
            return Object.entries(obj).find(([, name]) => value === name);
          }
          
          const [ key ] = getKeyByValue(obj, 'Den');
          console.log(key)
            

          【讨论】:

            【解决方案6】:

            使用Underscore.js 库:

            var hash = {
              foo: 1,
              bar: 2
            };
            
            (_.invert(hash))[1]; // => 'foo'
            

            【讨论】:

            • @GeorgeJempty 不是每个人都想加载一个 5kb 的库来进行简单的密钥查找;)
            • 仅供参考,供任何寻求解决方案的人使用,该解决方案将为您提供与值匹配的所有键:这是行不通的。
            • 下划线键也可以。 underscorejs.org/#keys_.keys({一:1,二:2,三:3}); => [“一”、“二”、“三”]
            • _.invert 在值包含对象的情况下不起作用,因为默认字符串序列化发生冲突。你可能会使用这个可憎的东西:_.chain(hash).pairs().findWhere({1: 1}).value()[0]
            • 这不应该是公认的答案,它通过一个库提出了一个解决方案,强制改变当前的代码结构
            【解决方案7】:

            给定input={"a":"x", "b":"y", "c":"x"} ...

            • 使用第一个值(例如output={"x":"a","y":"b"}):

            input = {
              "a": "x",
              "b": "y",
              "c": "x"
            }
            output = Object.keys(input).reduceRight(function(accum, key, i) {
              accum[input[key]] = key;
              return accum;
            }, {})
            console.log(output)
            • 使用最后一个值(例如output={"x":"c","y":"b"}):

            input = {
              "a": "x",
              "b": "y",
              "c": "x"
            }
            output = Object.keys(input).reduce(function(accum, key, i) {
              accum[input[key]] = key;
              return accum;
            }, {})
            console.log(output)
            • 获取每个值的键数组(例如output={"x":["c","a"],"y":["b"]}):

            input = {
              "a": "x",
              "b": "y",
              "c": "x"
            }
            output = Object.keys(input).reduceRight(function(accum, key, i) {
              accum[input[key]] = (accum[input[key]] || []).concat(key);
              return accum;
            }, {})
            console.log(output)

            【讨论】:

            • 这绝对是最好的答案,但我正在摸索一种转换它的方法,以便只返回给定对象的键,即在功能上等同于数组的 indexOf。
            • 除非内存是一种限制,并且您愿意花费大量的处理能力来多次查看对象,否则只需将上述“输出”保存到变量中并查找结果在那里......就像output['x']。你问的是这个吗?
            【解决方案8】:

            ES6 方法:

            Object.fromEntries(Object.entries(a).map(b => b.reverse()))['value_you_look_for']
            

            【讨论】:

              【解决方案9】:

              如果您正在使用 UnderscoreLodash 库,则可以使用 _.findKey 函数:

              var users = {
                'barney':  { 'age': 36, 'active': true },
                'fred':    { 'age': 40, 'active': false },
                'pebbles': { 'age': 1,  'active': true }
              };
              
              _.findKey(users, function(o) { return o.age < 40; });
              // => 'barney' (iteration order is not guaranteed)
              
              // The `_.matches` iteratee shorthand.
              _.findKey(users, { 'age': 1, 'active': true });
              // => 'pebbles'
              
              // The `_.matchesProperty` iteratee shorthand.
              _.findKey(users, ['active', false]);
              // => 'fred'
              
              // The `_.property` iteratee shorthand.
              _.findKey(users, 'active');
              // => 'barney'
              

              【讨论】:

                【解决方案10】:
                function getKeyByValue(object, value) {
                  return Object.keys(object).find(key => object[key] === value);
                }
                

                ES6,没有原型突变或外部库。

                例子,

                function getKeyByValue(object, value) {
                  return Object.keys(object).find(key => object[key] === value);
                }
                
                
                const map = {"first" : "1", "second" : "2"};
                console.log(getKeyByValue(map,"2"));

                【讨论】:

                • 好吧,如果你不支持 IE11,那真的很干净 :-)如果是这样,你需要一个 polyfill
                • 取决于实现,这可能需要 O(n) 空间,因为keys() 实现了密钥集。
                • 如果多个键的值相同,则使用过滤器而不是查找function getKeyByValue(object, value) { return Object.keys(object).filter(key =&gt; object[key] === value); }
                • 大声笑。这并不慢,它的 O(n) 几乎是最好的运行时。
                • @BenWainwright:维护BiMap 或等价物(Alethes 的回答)通常是解决更广泛问题的有效 O(1) 方法,但即使是一次性的,也至少可以使用 @ 进行迭代987654326@ 并在找到匹配项时中断,而不是提前创建整个键数组,从而导致最佳情况优于最坏情况。也就是说,O(position) 而不是 O(size)。 (这个页面上唯一比 O(size) 更糟糕的答案是愚蠢的 JSON 答案。)
                【解决方案11】:

                保持简单!

                您不需要通过复杂的方法或库过滤对象,Javascript 有一个名为 Object.values 的内置函数。

                例子:

                let myObj = {jhon: {age: 20, job: 'Developer'}, marie: {age: 20, job: 
                'Developer'}};
                
                function giveMeTheObjectData(object, property) {
                   return Object.values(object[property]);
                }
                
                giveMeTheObjectData(myObj, 'marie'); // => returns marie: {}
                

                这将返回对象属性数据。

                参考文献

                https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Object/values

                【讨论】:

                  【解决方案12】:

                  这是我的解决方案:

                  例如,我假设我们有一个包含三个值对的对象:

                  function findKey(object, value) {
                  
                      for (let key in object)
                          if (object[key] === value) return key;
                  
                      return "key is not found";
                  }
                  
                  const object = { id_1: "apple", id_2: "pear", id_3: "peach" };
                  
                  console.log(findKey(object, "pear"));
                  //expected output: id_2
                  

                  我们可以简单地编写一个 findKey(array, value) ,它接受两个参数,一个对象和您要查找的键的值。因此,此方法是可重用的,您无需每次都手动迭代对象,只需为此函数传递两个参数。

                  【讨论】:

                    【解决方案13】:

                    如前所述,需要迭代。例如,在现代浏览器中,您可以:

                    var key = Object.keys(obj).filter(function(key) {return obj[key] === value})[0];
                    

                    value 包含您要查找的值。 说了这么多,我可能会使用循环。

                    否则,您可以使用适当的“hashmap”对象 - JS 中有几种实现方式 - 或者您自己实现。

                    2018 年更新

                    六年过去了,但我仍然在这里获得了一些投票,所以我觉得应该在答案本身而不只是在 cmets 中提及更现代的解决方案 - 适用于现代浏览器/环境:

                    const key = Object.keys(obj).find(key => obj[key] === value);
                    

                    当然也可以是函数:

                    const getKeyByValue = (obj, value) => 
                            Object.keys(obj).find(key => obj[key] === value);
                    

                    【讨论】:

                    • ES6: Object.keys(obj).or(o=&gt;o[key] === value)
                    • 不幸的是,箭头功能还不是任何“现代”浏览器,所以目前它有点没用——我在 Firefox Nightly 的 jetpack 中使用它,它将在 Firefox 22 中使用。无论如何,我不知道任何or 数组的方法,我也不清楚它的目的:我会欣赏一些额外的细节! :)
                    • 至于箭头,它来了,我在等它:) 至于or,当然!它最近才被评估和接受(我认为还没有人实施它)。它所做的是找到与谓词匹配的数组的第一个元素并将其返回。所以[1,2,3,4].or(x=&gt;x&gt;2) 会返回3[1,2,3,4,5].or(x=&gt;x&lt;3) 会返回1。类似于 C# 的 FirstOrDefault :)
                    • 是的,arrow 即将到来,但它需要被广泛使用——除非像我一样,有人正在开发特定的引擎。我不知道 ES6 的新提案,我认为已经很封闭了:你有关于 or 方法的链接吗?从您提到的内容来看,它似乎返回了与谓词“或”数组本身匹配的项目?
                    • @sg552 后面会提到,or 改名了。我相信现在你应该使用find
                    【解决方案14】:

                    真的很简单。

                    const CryptoEnum = Object.freeze({
                                        "Bitcoin": 0, "Ethereum": 1, 
                                        "Filecoin": 2, "Monero": 3, 
                                        "EOS": 4, "Cardano": 5, 
                                        "NEO": 6, "Dash": 7, 
                                        "Zcash": 8, "Decred": 9 
                                      });
                    
                    Object.entries(CryptoEnum)[0][0]
                    // output => "Bitcoin"
                    

                    【讨论】:

                      【解决方案15】:

                      下划线js解决方案

                      let samplLst = [{id:1,title:Lorem},{id:2,title:Ipsum}]
                      let sampleKey = _.findLastIndex(samplLst,{_id:2});
                      //result would be 1
                      console.log(samplLst[sampleKey])
                      //output - {id:2,title:Ipsum}
                      

                      【讨论】:

                        【解决方案16】:

                        保持你的原型干净。

                        function val2key(val,array){
                            for (var key in array) {
                                if(array[key] == val){
                                    return key;
                                }
                            }
                         return false;
                        }
                        

                        例子:

                        var map = {"first" : 1, "second" : 2};
                        var key = val2key(2,map); /*returns "second"*/
                        

                        【讨论】:

                          【解决方案17】:

                          这里有一个 Lodash 解决方案,它适用于 flat key => value 对象,而不是嵌套对象。接受的答案建议使用_.findKey 适用于具有嵌套对象的对象,但在这种常见情况下不起作用。

                          这种方法反转对象,用键交换值,然后通过在新(反转)对象上查找值来找到键。如果未找到密钥,则返回 false,我更喜欢 undefined,但您可以轻松地将其替换为 getKey()_.get 方法的第三个参数。

                          // Get an object's key by value
                          var getKey = function( obj, value ) {
                          	var inverse = _.invert( obj );
                          	return _.get( inverse, value, false );
                          };
                          
                          // US states used as an example
                          var states = {
                          	"AL": "Alabama",
                          	"AK": "Alaska",
                          	"AS": "American Samoa",
                          	"AZ": "Arizona",
                          	"AR": "Arkansas",
                          	"CA": "California",
                          	"CO": "Colorado",
                          	"CT": "Connecticut",
                          	"DE": "Delaware",
                          	"DC": "District Of Columbia",
                          	"FM": "Federated States Of Micronesia",
                          	"FL": "Florida",
                          	"GA": "Georgia",
                          	"GU": "Guam",
                          	"HI": "Hawaii",
                          	"ID": "Idaho",
                          	"IL": "Illinois",
                          	"IN": "Indiana",
                          	"IA": "Iowa",
                          	"KS": "Kansas",
                          	"KY": "Kentucky",
                          	"LA": "Louisiana",
                          	"ME": "Maine",
                          	"MH": "Marshall Islands",
                          	"MD": "Maryland",
                          	"MA": "Massachusetts",
                          	"MI": "Michigan",
                          	"MN": "Minnesota",
                          	"MS": "Mississippi",
                          	"MO": "Missouri",
                          	"MT": "Montana",
                          	"NE": "Nebraska",
                          	"NV": "Nevada",
                          	"NH": "New Hampshire",
                          	"NJ": "New Jersey",
                          	"NM": "New Mexico",
                          	"NY": "New York",
                          	"NC": "North Carolina",
                          	"ND": "North Dakota",
                          	"MP": "Northern Mariana Islands",
                          	"OH": "Ohio",
                          	"OK": "Oklahoma",
                          	"OR": "Oregon",
                          	"PW": "Palau",
                          	"PA": "Pennsylvania",
                          	"PR": "Puerto Rico",
                          	"RI": "Rhode Island",
                          	"SC": "South Carolina",
                          	"SD": "South Dakota",
                          	"TN": "Tennessee",
                          	"TX": "Texas",
                          	"UT": "Utah",
                          	"VT": "Vermont",
                          	"VI": "Virgin Islands",
                          	"VA": "Virginia",
                          	"WA": "Washington",
                          	"WV": "West Virginia",
                          	"WI": "Wisconsin",
                          	"WY": "Wyoming"
                          };
                          
                          console.log( 'The key for "Massachusetts" is "' + getKey( states, 'Massachusetts' ) + '"' );
                          &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"&gt;&lt;/script&gt;

                          【讨论】:

                            【解决方案18】:

                            不可迭代的解决方案

                            主要功能:

                            var keyByValue = function(value) {
                            
                                var kArray = Object.keys(greetings);        // Creating array of keys
                                var vArray = Object.values(greetings);      // Creating array of values
                                var vIndex = vArray.indexOf(value);         // Finding value index 
                            
                                return kArray[vIndex];                      // Returning key by value index
                            }
                            

                            具有键和值的对象:

                            var greetings = {
                                english   : "hello",
                                ukranian  : "привіт"
                            };
                            

                            测试:

                            keyByValue("привіт");
                            // => "ukranian"
                            

                            【讨论】:

                            • 更简单:Object.keys(greetings )[Object.values(greetings ).indexOf('привіт')]
                            【解决方案19】:
                            function extractKeyValue(obj, value) {
                                return Object.keys(obj)[Object.values(obj).indexOf(value)];
                            }
                            

                            用于闭包编译器提取编译后未知的键名

                            更性感的版本,但使用未来的Object.entries 功能

                            function objectKeyByValue (obj, val) {
                              return Object.entries(obj).find(i => i[1] === val);
                            }
                            

                            【讨论】:

                            • 我认为这是 2017+ 年最好的版本,因为它使用纯 JavaScript。
                            • 如果您有两个或多个具有相同值的数字似乎不起作用
                            • @SamuelChen 没错,但如果它有效,则意味着需要一个数组。其中Object.entries(obj).find(i =&gt; i[1] === val); 使用filter 而不是Object.entries(obj).filter(i =&gt; i[1] === val);
                            • 使用解构让它变得更好Object.entries(obj).find( ([ key, value ]) =&gt; value === val);
                            • 您获得了截至 2021 年最快的解决方案。 Object.values(...).find(...) 对于 15 个属性对象来说要慢 10%,我想知道这对一个大物体。
                            【解决方案20】:

                            好像这个问题还没有被打到纸浆......

                            这里有一个只是为了满足您的好奇心......

                            如果您确定您的对象将只有字符串值,那么您真的可以用尽自己的力量来想出这个实现:

                            var o = { a: '_A', b: '_B', c: '_C' }
                              , json = JSON.stringify(o)
                              , split = json.split('')
                              , nosj = split.reverse()
                              , o2 = nosj.join('');
                            
                            var reversed = o2.replace(/[{}]+/g, function ($1) { return ({ '{':'}', '}':'{' })[$1]; })
                              , object = JSON.parse(reversed)
                              , value = '_B'
                              , eulav = value.split('').reverse().join('');
                            
                            console.log('>>', object[eulav]);
                            

                            也许这里有一些有用的东西可以构建......

                            希望这能让你开心。

                            【讨论】:

                              【解决方案21】:

                              lodash 方式https://lodash.com/docs#findKey

                              var users = {
                                'barney':  { 'age': 36, 'active': true },
                                'fred':    { 'age': 40, 'active': false },
                                'pebbles': { 'age': 1,  'active': true }
                              };
                              
                              _.findKey(users, { 'age': 1, 'active': true });
                              // → 'pebbles'

                              【讨论】:

                              • Lodash 显然是解决这个问题的最佳方案。我发现,甚至比下划线方式更好。
                              • 仅供参考,“下划线方式”:_.findKey(users, { 'age': 1, 'active': true }); ...它是一样的
                              • 如果您的值很简单,例如字符串或整数,那么与预期相反,这将不起作用。例如_.find_key({a: "A", b:"B"}, "B"})returnsundefined 如此说明here 你需要做_.find_key({a: "A", b:"B"}, _.partial(_.isEqual,"B")})
                              • @ryan2johnson9 这是我对 Lodash 的问题。我很难理解一些功能(显然我是唯一的)。但无论如何,谢谢,它有效。我找到了另一个更短的解决方案。它会导致更大的对象过堆,所以要小心这个。 _.invert(haystack)[needle]
                              • 要扩展@ryan2johnson9 的注释,当值是原始值(字符串、整数等)时,您需要使用_.findKey({a: "A", b: "B"}, value =&gt; value === "B") // =&gt; "b",因为第二个参数是谓词。简写 _.findKey({...}, "B") 将查找名为 B 的属性:{b: { B: ... } }
                              【解决方案22】:

                              我通常推荐 lodash 而不是下划线。

                              如果你有,请使用它。

                              如果你不这样做,那么你应该考虑使用非常小的 lodash.invert npm 包。

                              以下是使用 gulp 对其进行测试的方法:

                              1) 创建一个名为 gulpfile.js 的文件,其内容如下:

                              // Filename: gulpfile.js
                              var gulp = require('gulp');
                              var invert = require('lodash.invert');   
                              gulp.task('test-invert', function () {
                                var hash = {
                                  foo: 1,
                                  bar: 2
                                };
                                var val = 1;
                                var key = (invert(hash))[val];  // << Here's where we call invert!
                                console.log('key for val(' + val + '):', key);
                              });
                              

                              2) 安装 lodash.invert 包和 gulp

                              $ npm i --save lodash.invert && npm install gulp
                              

                              3) 测试它是否有效:

                              $ gulp test-invert
                              [17:17:23] Using gulpfile ~/dev/npm/lodash-invert/gulpfile.js
                              [17:17:23] Starting 'test-invert'...
                              key for val(1): foo
                              [17:17:23] Finished 'test-invert' after 511 μs
                              

                              参考文献

                              https://www.npmjs.com/package/lodash.invert

                              https://lodash.com/

                              Differences between lodash and underscore

                              https://github.com/gulpjs/gulp

                              【讨论】:

                              • Gulp 为什么要参与其中?只需运行脚本...
                              【解决方案23】:

                              没有可用的标准方法。你需要迭代,你可以创建一个简单的助手:

                              Object.prototype.getKeyByValue = function( value ) {
                                  for( var prop in this ) {
                                      if( this.hasOwnProperty( prop ) ) {
                                           if( this[ prop ] === value )
                                               return prop;
                                      }
                                  }
                              }
                              
                              var test = {
                                 key1: 42,
                                 key2: 'foo'
                              };
                              
                              test.getKeyByValue( 42 );  // returns 'key1'
                              

                              请注意:即使上述方法有效,扩展任何主机或本机对象的.prototype 通常也是个坏主意。我在这里这样做是因为它非常适合这个问题。无论如何,您可能应该在.prototype 之外使用此函数并将对象传递给它。

                              【讨论】:

                              • 实际上,如果你知道 for-in 循环沿着属性链向下走,这意味着“for(var key in obj)”在某些情况下会给你“getKeyByValue”作为“key”,那也没关系点。
                              • 哦,天哪,如果值不存在,我喜欢这个秘密返回 undefined 的方式。做得好。此外,这只是一个兴趣点,这将执行 O(n),因此如果对象具有大量属性(例如大城市中的人员列表及其地址),您可能需要更有效的搜索。也许排序值和二进制搜索?嗯?
                              • 非常感谢,当我看到坏主意时,我想知道为什么然后我搜索了这个并在此处添加了这个答案增强和广泛阅读。 stackoverflow.com/questions/3085240/…
                              • @jAndy 它不是 ===,它是 ==。您的代码不适用于 ===。它返回未定义。
                              • 我认为将其转换为字符串会更好地修复类型错误,只需添加 .toString()(如 obj[ key ].toString())并在需要时添加值...
                              【解决方案24】:

                              我创建了 bimap 库 (https://github.com/alethes/bimap),它实现了一个强大、灵活和高效的 JavaScript 双向地图接口。它没有依赖关系,可用于服务器端(在 Node.js 中,您可以使用 npm install bimap 安装它)和浏览器中(通过链接到 lib/bimap.js)。

                              基本操作真的很简单:

                              var bimap = new BiMap;
                              bimap.push("k", "v");
                              bimap.key("k") // => "v"
                              bimap.val("v") // => "k"
                              
                              bimap.push("UK", ["London", "Manchester"]);
                              bimap.key("UK"); // => ["London", "Manchester"]
                              bimap.val("London"); // => "UK"
                              bimap.val("Manchester"); // => "UK"
                              

                              键值映射的检索在两个方向上都同样快。引擎盖下没有代价高昂的对象/数组遍历,因此无论数据大小如何,平均访问时间都保持不变。

                              【讨论】:

                              • 唯一不需要迭代的解决方案之一(在解决方案本身、标准库或其他库中)。
                              【解决方案25】:

                              这是对 Underscorejs 方法的一个小扩展,使用 Lodash 代替:

                              var getKeyByValue = function(searchValue) {
                                return _.findKey(hash, function(hashValue) {
                                  return searchValue === hashValue;
                                });
                              }
                              

                              FindKey 将匹配该值的search and return the first key
                              如果您想要最后一场比赛,请改用FindLastKey

                              【讨论】:

                                【解决方案26】:

                                由于这些值是唯一的,因此应该可以将这些值添加为一组额外的键。这可以通过以下快捷方式完成。

                                var foo = {};
                                foo[foo.apple = "an apple"] = "apple";
                                foo[foo.pear = "a pear"] = "pear";
                                

                                这将允许通过键或值进行检索:

                                var key = "apple";
                                var value = "an apple";
                                
                                console.log(foo[value]); // "apple"
                                console.log(foo[key]); // "an apple"
                                

                                这确实假设键和值之间没有共同的元素。

                                【讨论】:

                                • 唯一不需要迭代的解决方案之一(在解决方案本身、标准库或其他库中)。
                                • OP 确实说过键/值对都是唯一的,因此这个低技术的答案真是太棒了!干得好;)
                                【解决方案27】:

                                或者,更简单 - 按照您想要的顺序使用键和值创建一个新对象,然后查找该对象。我们在使用上面的原型代码时遇到了冲突。您不必在键周围使用 String 函数,这是可选的。

                                 newLookUpObj = {};
                                 $.each(oldLookUpObj,function(key,value){
                                        newLookUpObj[value] = String(key);
                                    });
                                

                                【讨论】:

                                  【解决方案28】:

                                  http://jsfiddle.net/rTazZ/2/

                                  var a = new Array(); 
                                      a.push({"1": "apple", "2": "banana"}); 
                                      a.push({"3": "coconut", "4": "mango"});
                                  
                                      GetIndexByValue(a, "coconut");
                                  
                                      function GetIndexByValue(arrayName, value) {  
                                      var keyName = "";
                                      var index = -1;
                                      for (var i = 0; i < arrayName.length; i++) { 
                                         var obj = arrayName[i]; 
                                              for (var key in obj) {          
                                                  if (obj[key] == value) { 
                                                      keyName = key; 
                                                      index = i;
                                                  } 
                                              } 
                                          }
                                          //console.log(index); 
                                          return index;
                                      } 
                                  

                                  【讨论】:

                                  【解决方案29】:

                                  我使用这个功能:

                                  Object.prototype.getKey = function(value){
                                    for(var key in this){
                                      if(this[key] == value){
                                        return key;
                                      }
                                    }
                                    return null;
                                  };
                                  

                                  用法:

                                  // ISO 639: 2-letter codes
                                  var languageCodes = {
                                    DA: 'Danish',
                                    DE: 'German',
                                    DZ: 'Bhutani',
                                    EL: 'Greek',
                                    EN: 'English',
                                    EO: 'Esperanto',
                                    ES: 'Spanish'
                                  };
                                  
                                  var key = languageCodes.getKey('Greek');
                                  console.log(key); // EL
                                  

                                  【讨论】:

                                  • +1 简洁的解决方案。但我有一个问题:你不应该总是检查obj.hasOwnProperty(key) 还是在这种情况下没有必要?
                                  • 改变对象原型是不好的做法:stackoverflow.com/questions/23807805/…
                                  猜你喜欢
                                  • 2012-07-20
                                  • 2021-12-25
                                  • 2016-08-21
                                  • 2019-04-11
                                  • 1970-01-01
                                  • 2016-10-05
                                  • 2018-04-18
                                  相关资源
                                  最近更新 更多