私は連想配列として使用する非常に単純なJavaScriptオブジェクトを持っています。値のキーを取得できる単純な関数はありますか、それともオブジェクトを反復して手動で見つける必要がありますか?
var o = []; var map = {first: o, second: o}
。何がfind_key(o)
返りますか?
私は連想配列として使用する非常に単純なJavaScriptオブジェクトを持っています。値のキーを取得できる単純な関数はありますか、それともオブジェクトを反復して手動で見つける必要がありますか?
var o = []; var map = {first: o, second: o}
。何がfind_key(o)
返りますか?
回答:
Underscore.jsのライブラリ:
var hash = {
foo: 1,
bar: 2
};
(_.invert(hash))[1]; // => 'foo'
_.chain(hash).pairs().findWhere({1: 1}).value()[0]
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"));
keys()
必要とします。
function getKeyByValue(object, value) { return Object.keys(object).filter(key => object[key] === value); }
利用できる標準的な方法はありません。反復する必要があり、単純なヘルパーを作成できます。
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
し、代わりにオブジェクトをそれに渡す必要があります。
.toString()
のようにobj[ key ].toString()
...必要に応じて値とに
言ったように、反復が必要です。たとえば、最新のブラウザでは次のようになります。
var key = Object.keys(obj).filter(function(key) {return obj[key] === value})[0];
どこ value
探している値が含まれる。それは、おそらくループを使用するだろうと言いました。
それ以外の場合は、適切な「ハッシュマップ」オブジェクトを使用できます-JSにはいくつかの実装があります-または独自に実装します。
2018年の更新
6年が経過しましたが、私はまだここで投票しています。そのため、コメントだけでなく、回答自体にも最新のブラウザー/環境向けのより最新のソリューションを記載する必要があると思います。
const key = Object.keys(obj).find(key => obj[key] === value);
もちろんそれは関数にすることもできます:
const getKeyByValue = (obj, value) =>
Object.keys(obj).find(key => obj[key] === value);
Object.keys(obj).or(o=>o[key] === value)
or
配列のことは知りませんメソッド、そしてそれは私にはここではその目的が明確ではありません:私はいくつかの追加の詳細に感謝します!:)
or
確かに!最近になって評価され、受け入れられました(まだ実装していないと思います)。それが行うことは、述語に一致する配列の最初の要素を見つけてそれを返すことです。だから、[1,2,3,4].or(x=>x>2)
戻ってくる3
と[1,2,3,4,5].or(x=>x<3)
返します1
。C#のFirstOrDefault :)のようなもの
or
。この方法に関するリンクはありますか?あなたが言ったことから、それは述語「または」配列自体に一致するアイテムを返すようですか?
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'
_.findKey(users, { 'age': 1, 'active': true });
...それは同じ
_.find_key({a: "A", b:"B"}, "B"})
があるリターンundefined
_.find_key({a: "A", b:"B"}, _.partial(_.isEqual,"B")})
_.invert(haystack)[needle]
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);
}
Object.entries(obj).find(i => i[1] === val);
使用する場所filter
Object.entries(obj).filter(i => i[1] === val);
Object.entries(obj).find( ([ key, value ]) => value === val);
ES6 +ワンライナー
let key = Object.keys(obj).find(k=>obj[k]===value);
次の値を持つすべてのキーを返します。
let keys = Object.keys(obj).filter(k=>obj[k]===value);
私はこの関数を使用します:
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
obj.hasOwnProperty(key)
この場合、常に確認する必要はありませんか、それとも不要ですか?
非反復可能ソリューション
主な機能:
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('привіт')]
あなたが作業している場合はアンダースコアまたはLodashライブラリは、使用することができます_.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'
私は、強力で柔軟かつ効率的なJavaScript双方向マップインターフェイスを実装するbimapライブラリ(https://github.com/alethes/bimap)を作成しました。これは依存関係がなく、サーバー側(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"
キーと値のマッピングの取得は、両方向で同等に高速です。コストのかかるオブジェクト/配列トラバーサルは内部に存在しないため、データのサイズに関係なく、平均アクセス時間は一定のままです。
値は一意であるため、キーの追加セットとして値を追加できるはずです。これは、次のショートカットで実行できます。
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"
これは、キーと値の間に共通の要素がないことを前提としています。
与えられた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)
output['x']
。それはあなたが求めていたものですか?
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;
}
または、さらに簡単です-キーと値を使用して新しいオブジェクトを作成し、そのオブジェクトに対してルックアップを行います。上記のプロトタイプコードを使用して競合が発生しました。キーの周りにString関数を使用する必要はありません。これはオプションです。
newLookUpObj = {};
$.each(oldLookUpObj,function(key,value){
newLookUpObj[value] = String(key);
});
好奇心があなたにもたらすものをここに示します...
オブジェクトに文字列値のみが含まれていると確信している場合は、この実装を思い起こさせるために本当に疲れ果てることができます。
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]);
たぶんここから構築するのに役立つ何かがあるでしょう...
これがあなたを楽しませるといいのですが。
これに対するLodashソリューションは、ネストされたオブジェクトではなく、フラットキー=>値オブジェクトに対して機能します。受け入れられた回答の使用に関する提案_.findKey
ことは、ネストされたオブジェクトを持つオブジェクト機能しますが、この一般的な状況では機能しません。
このアプローチでは、オブジェクトを反転させ、キーを値に交換し、新しい(反転された)オブジェクトの値を検索してキーを見つけます。キーが見つからない場合false
はが返されますが、これは優先されundefined
ますが、これをの_.get
メソッドの3番目のパラメーターで簡単に交換できますgetKey()
。
// 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' ) + '"' );
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
これが私の解決策です:
たとえば、3つの値のペアを含むオブジェクトがあるとします。
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
オブジェクトと検索するキーの値である2つのパラメーターを取るfindKey(array、value)を記述するだけです。そのため、このメソッドは再利用可能であり、この関数に2つのパラメータを渡すだけで毎回オブジェクトを手動で繰り返す必要はありません。
私は通常、アンダースコアよりもロダッシュをお勧めします。
お持ちの方はご利用ください。
そうでない場合は、かなり小さい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
参考文献
本当に簡単です。
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"
複雑にしないでおく!
洗練されたメソッドやライブラリでオブジェクトをフィルタリングする必要はありません。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