چگونه میتوان در یک شیء جاوااسکریپت بر اساس مقدار آن کلید را به دست آورد؟


من یک شیء جاوااسکریپت نسبتاً ساده دارم که از آن به عنوان یک آرایه انجمنی استفاده میکنم. آیا تابع سادهای وجود دارد که به من اجازه دهد کلید مربوط به یک مقدار را بدست آورم، یا باید به صورت دستی شیء را پیمایش کنم و آن را پیدا کنم؟

پاسخ شماره ۱

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

پاسخ شماره ۲

هیچ روش استانداردی در دسترس نیست. شما نیاز دارید که تکرار کنید و میتوانید یک کمککننده ساده ایجاد کنید:

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 استفاده کنید و شیء را به آن ارسال کنید.

پاسخ شماره ۳

همانطور که گفته شد، تکرار لازم است. برای مثال، در مرورگرهای مدرن میتوانید داشته باشید:

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

جایی که value شامل مقداری است که به دنبال آن هستید. با این حال، احتمالاً از یک حلقه استفاده میکردم.

در غیر این صورت میتوانید از یک شیء «hashmap» مناسب استفاده کنید - چندین پیادهسازی در جاوااسکریپت وجود دارد - یا خودتان آن را پیادهسازی کنید.

بهروزرسانی ۲۰۱۸

شش سال گذشت، اما من هنوز اینجا رأی میگیرم، بنابراین احساس میکنم یک راهحل مدرنتر - برای مرورگر/محیط مدرن - باید در خود جواب ذکر شود و نه فقط در نظرات:

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

البته این میتواند همچنین یک تابع باشد:

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

پاسخ شماره ۴

کوتاهترین جملات تکخطی

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

تمام کلیدها با مقدار را برگردان:

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

اگر مقدار یک آرایه یا شیء باشد:

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

پاسخ شماره ۵

با کتابخانه Underscore.js:

var hash = {
  foo: 1,
  bar: 2
};

(_.invert(hash))[1]; // => 'foo'

پاسخ شماره ۶

روش 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)];
}

ساخته شده برای کامپایلر Closure برای استخراج نام کلیدی که پس از کامپایل ناشناخته خواهد بود

نسخهای جذابتر اما با استفاده از تابع آینده Object.entries

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

ویرایش ۲۰۲۳: اگرچه .entries() اکنون به طور گسترده پشتیبانی میشود، در نهایت نسخه اول هنوز بهتر است زیرا به جای تکرار روی یک کالبک JS، از indexOf بومی استفاده میکند.

پاسخ شماره ۸

من از این تابع استفاده میکنم:

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

پاسخ شماره ۹

راهحل غیرتکرارشونده

تابع اصلی:

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"

پاسخ شماره ۱۰

نمونه اولیه خود را تمیز نگه دارید.

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"*/

پاسخ شماره ۱۱

من کتابخانه 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"

بازیابی نگاشت کلید-مقدار در هر دو جهت به یک سرعت انجام میشود. هیچ پیمایش پرهزینهای از شیء/آرایه در پسزمینه وجود ندارد، بنابراین زمان دسترسی متوسط، صرفنظر از اندازه دادهها، ثابت باقی میماند.

پاسخ شماره ۱۲

اگر شما با کتابخانه Underscore یا 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'

پاسخ شماره ۱۳

این برای من کار کرد تا کلید/مقدار شیء را بگیرم.

let obj = {
  'key1': 'value1',
  'key2': 'value2',
  'key3': 'value3',
  'key4': 'value4'
}

Object.keys(obj).map(function(k) {
  console.log("key with value: " + k + " = " + obj[k])
})