J'ai un objet JavaScript assez simple, que j'utilise comme un tableau associatif. Existe-t-il une fonction simple permettant d’obtenir la clé d’une valeur ou dois-je itérer l’objet et le rechercher manuellement?
avec Underscore.js
bibliothèque:
_var hash = {
foo: 1,
bar: 2
};
(_.invert(hash))[1]; // => 'foo'
_
function getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
}
ES6, pas de mutations prototypes ni de bibliothèques externes.
Exemple,
function getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
}
const map = {"first" : "1", "second" : "2"};
console.log(getKeyByValue(map,"2"));
Aucune méthode standard disponible. Vous devez itérer et vous pouvez créer un assistant simple:
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'
n mot d'avertissement: Même si cela fonctionne, c'est généralement une mauvaise idée d'étendre tout .prototype
de l'hôte ou de l'objet natif. Je l'ai fait ici parce que cela cadre très bien avec le problème. Quoi qu'il en soit, vous devriez probablement utiliser cette fonction en dehors de .prototype
et lui passer l'objet à la place.
Comme dit, l'itération est nécessaire. Par exemple, dans un navigateur moderne, vous pourriez avoir:
var key = Object.keys(obj).filter(function(key) {return obj[key] === value})[0];
Où value
contient la valeur que vous recherchez. Cela dit, j'utiliserais probablement une boucle.
Sinon, vous pouvez utiliser un objet "hashmap" approprié - il y a plusieurs implémentations dans JS autour - ou implémenter vous-même.
MISE À JOUR 2018
Six ans ont passé, mais je reçois encore des votes ici, donc je me sens comme une solution plus moderne - pour les navigateurs/environnements modernes - devrait être mentionnée dans la réponse elle-même et pas seulement dans les commentaires:
const key = Object.keys(obj).find(key => obj[key] === value);
Bien sûr cela peut être aussi une fonction:
const getKeyByValue = (obj, value) =>
Object.keys(obj).find(key => obj[key] === value);
La méthode 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'
function extractKeyValue(obj, value) {
return Object.keys(obj)[Object.values(obj).indexOf(value)];
}
Conçu pour le compilateur de fermeture pour extraire le nom de la clé qui sera inconnu après la compilation
Version plus sexy mais utilisant la future fonction Object.entries
]
function objectKeyByValue (obj, val) {
return Object.entries(obj).find(i => i[1] === val);
}
J'utilise cette fonction:
Object.prototype.getKey = function(value){
for(var key in this){
if(this[key] == value){
return key;
}
}
return null;
};
tilisation:
// 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
Gardez votre prototype propre.
function val2key(val,array){
for (var key in array) {
if(array[key] == val){
return key;
}
}
return false;
}
Exemple:
var map = {"first" : 1, "second" : 2};
var key = val2key(2,map); /*returns "second"*/
Solution non-itérable
Fonction principale:
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
}
Objet avec clés et valeurs:
var greetings = {
english : "hello",
ukranian : "привіт"
};
Tester:
keyByValue("привіт");
// => "ukranian"
Si vous travaillez avec Underscore ou Lodash , vous pouvez utiliser le _. findKey fonction:
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'
J'ai créé la bibliothèque bimap ( https://github.com/alethes/bimap ) qui implémente une puissante, flexible et interface de carte JavaScript bidirectionnelle efficace. Il n'a pas de dépendances et est utilisable à la fois côté serveur (dans Node.js, vous pouvez l'installer avec npm install bimap
) et dans le navigateur (en vous connectant à lib/bimap .js ).
Les opérations de base sont vraiment simples:
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"
La récupération du mappage clé-valeur est également rapide dans les deux sens. Il n'y a pas de traversées coûteuses d'objets/de tableaux sous le capot, le temps d'accès moyen reste donc constant quelle que soit la taille des données.
Étant donné que les valeurs sont uniques, il devrait être possible de les ajouter en tant que jeu de clés supplémentaire. Cela pourrait être fait avec le raccourci suivant.
var foo = {};
foo[foo.Apple = "an Apple"] = "Apple";
foo[foo.pear = "a pear"] = "pear";
Cela permettrait la récupération via la clé ou la valeur:
var key = "Apple";
var value = "an Apple";
console.log(foo[value]); // "Apple"
console.log(foo[key]); // "an Apple"
Cela suppose qu'il n'y a pas d'éléments communs entre les clés et les valeurs.
Ou encore, encore plus facilement - créez un nouvel objet avec les clés et les valeurs dans l'ordre de votre choix, puis comparez-le avec cet objet. Nous avons eu des conflits en utilisant les codes prototypes ci-dessus. Vous n'êtes pas obligé d'utiliser la fonction Chaîne autour de la clé, c'est facultatif.
newLookUpObj = {};
$.each(oldLookUpObj,function(key,value){
newLookUpObj[value] = String(key);
});
En voici une juste pour la curiosité que cela vous amène ...
Si vous êtes certain que votre objet n'aura que des valeurs de chaîne, vous pouvez vraiment vous épuiser pour évoquer cette implémentation:
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]);
Peut-être qu'il y a quelque chose d'utile à construire à partir d'ici ...
J'espère que cela vous amuse.
Ceci est une petite extension de la méthode Underscorejs et utilise Lodash à la place:
var getKeyByValue = function(searchValue) {
return _.findKey(hash, function(hashValue) {
return searchValue === hashValue;
});
}
FindKey volonté recherche et retourne la première clé qui correspond à la valeur.
Si vous voulez plutôt la dernière correspondance, utilisez FindLastKey .
Voici une solution Lodash qui fonctionne pour une clé plate => objet de valeur, plutôt que pour un objet imbriqué. La suggestion de la réponse acceptée d'utiliser _.findKey
fonctionne pour les objets avec des objets imbriqués, mais cela ne fonctionne pas dans cette situation courante.
Cette approche inverse l'objet en échangeant des clés pour des valeurs, puis recherche la clé en recherchant la valeur sur le nouvel objet (inversé). Si la clé n'est pas trouvée, alors false
est renvoyé, ce que je préfère par rapport à undefined
, mais vous pouvez facilement le remplacer dans le troisième paramètre de la méthode _.get
de 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>
Je recommande généralement lodash plutôt que le soulignement.
Si vous en avez, utilisez-le.
Si vous ne le faites pas, vous devriez envisager d'utiliser le paquetage lodash.invert npm, qui est plutôt petit.
Voici comment vous pouvez le tester en utilisant gulp:
1) Créez un fichier appelé gulpfile.js avec le contenu suivant:
// 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) Installez le package lodash.invert et gulp
$ npm i --save lodash.invert && npm install gulp
3) Vérifiez que cela fonctionne:
$ 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
Références
https://www.npmjs.com/package/lodash.invert
Vraiment simple.
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"
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;
}
Voici ma solution d'abord:
Par exemple, je suppose que nous avons un objet qui contient trois paires de valeurs:
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
Nous pouvons simplement écrire un findKey (tableau, valeur) qui prend deux paramètres qui sont un objet et la valeur de la clé que vous recherchez. En tant que telle, cette méthode est réutilisable et il n’est pas nécessaire d’itérer manuellement l’objet à chaque fois en ne transmettant que deux paramètres à cette fonction.
Étant donné input={"a":"x", "b":"y", "c":"x"}
...
Pour utiliser la première valeur (par exemple output={"x":"a","y":"b"}
): output=Object.keys(input).reduceRight(function(accum,key,i){accum[input[key]]=key;return accum;},{})
Pour utiliser la dernière valeur (par exemple output={"x":"c","y":"b"}
): output=Object.keys(input).reduce(function(accum,key,i){accum[input[key]]=key;return accum;},{})
Pour obtenir un tableau de clés pour chaque valeur (par exemple output={"x":["c","a"],"y":["b"]}
): output=Object.keys(input).reduceRight(function(accum,key,i){accum[input[key]]=(accum[input[key]]||[]).concat(key);return accum;},{})
Souligner la solution 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}