ฉันมีวัตถุ 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()
materializes ชุดคีย์
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
มีค่าที่คุณกำลังมองหา กล่าวว่าฉันอาจจะใช้วง
มิฉะนั้นคุณสามารถใช้วัตถุ "hashmap" ที่เหมาะสม - มีการนำไปใช้งานหลายอย่างใน JS หรือ - ดำเนินการด้วยตนเอง
อัพเดท 2018
หกปีที่ผ่านมา แต่ฉันยังคงได้รับคะแนนบางส่วนที่นี่ดังนั้นฉันจึงรู้สึกเหมือนเป็นทางออกที่ทันสมัยกว่า - สำหรับเบราว์เซอร์ / สภาพแวดล้อมที่ทันสมัย - ควรได้รับการกล่าวถึงในคำตอบของตัวเองไม่ใช่เฉพาะในความคิดเห็นเท่านั้น:
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
บางอย่างเช่น FirstOrDefault ของ C #:
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);
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('привіт')]
รักษาความสะอาดต้นแบบของคุณ
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"*/
หากคุณทำงานกับUnderscoreหรือLodash library คุณสามารถใช้ฟังก์ชัน_.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'
ฉันสร้างห้องสมุด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"
การดึงข้อมูลของการจับคู่คีย์ - ค่ามีความรวดเร็วเท่ากันทั้งสองทิศทาง ไม่มีค่าใช้จ่ายในการสำรวจวัตถุ / อาร์เรย์ภายใต้ประทุนดังนั้นเวลาการเข้าถึงโดยเฉลี่ยจะคงที่ไม่ว่าขนาดของข้อมูลจะเป็นเท่าใดก็ตาม
ไม่เห็นสิ่งต่อไปนี้:
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)
เนื่องจากค่าไม่ซ้ำกันจึงควรเพิ่มค่าเป็นชุดคีย์เพิ่มเติม สามารถทำได้ด้วยทางลัดต่อไปนี้
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);
});
นี่เป็นส่วนขยายขนาดเล็กสำหรับวิธี Underscorejs และใช้Lodashแทน:
var getKeyByValue = function(searchValue) {
return _.findKey(hash, function(hashValue) {
return searchValue === hashValue;
});
}
FindKeyจะค้นหาและส่งคืนคีย์แรกที่ตรงกับค่า
หากคุณต้องการนัดสุดท้ายแทนให้ใช้ FindLastKeyแทน
นี่คือสิ่งที่คุณอยากรู้ ...
หากคุณแน่ใจว่าวัตถุของคุณจะมีค่าสตริงเท่านั้นคุณสามารถทำให้ตัวเองหมดตัวเพื่อคิดในการปรับใช้นี้:
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
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>
นี่คือทางออกของฉันก่อน:
ตัวอย่างเช่นฉันสมมติว่าเรามีวัตถุที่มีค่าสามคู่:
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) ที่รับพารามิเตอร์สองตัวซึ่งเป็นวัตถุและค่าของคีย์ที่คุณกำลังค้นหา ดังนั้นวิธีนี้สามารถนำมาใช้ซ้ำได้และคุณไม่จำเป็นต้องวนซ้ำวัตถุด้วยตนเองทุกครั้งโดยผ่านพารามิเตอร์สองตัวสำหรับฟังก์ชันนี้เท่านั้น
วิธีES6 :
Object.fromEntries(Object.entries(a).map(b => b.reverse()))['value_you_look_for']
ฉันมักจะแนะนำ lodash มากกว่าการขีดเส้นใต้
หากคุณมีมันใช้มัน
หากคุณไม่ทำเช่นนั้นคุณควรพิจารณาใช้แพ็คเกจ lodash.invert npm ซึ่งค่อนข้างเล็ก
นี่คือวิธีที่คุณสามารถทดสอบโดยใช้อึก:
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 แพ็คเกจและอึก
$ 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
ขีดเส้นใต้โซลูชัน 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}
สิ่งนี้ทำงานให้ฉันเพื่อรับคีย์ / ค่าของวัตถุ
let obj = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3',
'key4': 'value4'
}
Object.keys(obj).map(function(k){
console.log("key with value: "+k +" = "+obj[k])
})
ตรงไปตรงมาจริงๆ
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"
ง่าย ๆ เข้าไว้!
คุณไม่จำเป็นต้องกรองวัตถุด้วยวิธีการหรือ libs ที่ซับซ้อน Javascript มีฟังก์ชันในตัวที่เรียกว่าObject.values 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