সাম্প্রতিক দ্রষ্টব্য: আমি যখন এই উত্তরটি অনেকগুলি উত্সাহ পেয়েছি তা নিয়ে চাটুকার করার সময় আমিও কিছুটা আতঙ্কিত হয়েছি। যদি "xabc" এর মতো ডট-নোটেশন স্ট্রিংগুলিকে রেফারেন্সে রূপান্তর করতে হয় তবে এটি (সম্ভবত) একটি লক্ষণ হতে পারে যে এখানে খুব ভুল কিছু চলছে (যদি না আপনি কিছু অদ্ভুত deserialization করছেন তবে)।
এর অর্থ এই যে, যে উত্তরদাতারা এই উত্তরের পথ খুঁজে পান তাদের অবশ্যই নিজের কাছে প্রশ্ন জিজ্ঞাসা করতে হবে "আমি কেন এটি করছি?"
আপনার ব্যবহারের কেসটি যদি ছোট হয় এবং আপনি পারফরম্যান্সের সমস্যাগুলিতে না চলে যান তবে এটি করা সাধারণত আপনার পক্ষে ঠিক আছে এবং পরে এটি আরও জটিল করার জন্য আপনার বিমূর্ততাটি তৈরি করার প্রয়োজন হবে না। আসলে, যদি এটি কোডের জটিলতা হ্রাস করে এবং জিনিসগুলিকে সহজ রাখে, আপনার সম্ভবত এগিয়ে যাওয়া উচিত এবং ওপি যা চাইছে তা করা উচিত । তবে, যদি এটি না হয় তবে বিবেচনা করুন এগুলির কোনও প্রয়োগ হয় কিনা:
কেস 1 : আপনার ডেটা নিয়ে কাজ করার প্রাথমিক পদ্ধতি হিসাবে (যেমন আপনার অ্যাপ্লিকেশনটির চারপাশে অবজেক্টগুলি পাস করার এবং সেগুলি অবনমিত করার ডিফল্ট রূপ হিসাবে)। "আমি কীভাবে কোনও স্ট্রিং থেকে কোনও ফাংশন বা পরিবর্তনশীল নামটি সন্ধান করতে পারি" জিজ্ঞাসা করার মতো।
- এটি খারাপ প্রোগ্রামিং অনুশীলন (বিশেষত অপ্রয়োজনীয় রূপান্তরকরণ এবং একধরণের লঙ্ঘন ফাংশন সাইড-এফেক্ট-মুক্ত কোডিং শৈলীতে রয়েছে এবং এতে পারফরম্যান্স হিট হবে)। এই ক্ষেত্রে নিজেকে যে নোটিশগুলি আবিষ্কার করে, তাদের পরিবর্তে অ্যারের উপস্থাপনাগুলির সাথে কাজ করা বিবেচনা করা উচিত, যেমন ['x', 'ক', 'বি', 'সি'], অথবা সম্ভব হলে আরও সরাসরি / সরল / সোজা কিছু: হারানো না যেমন প্রথমদিকে তাদের উল্লেখগুলির ট্র্যাক করুন (সবচেয়ে আদর্শ যদি এটি কেবল ক্লায়েন্ট-সাইড বা কেবল সার্ভার-সাইড) হয়, ইত্যাদি ((পূর্ব-বিদ্যমান ইউনিক আইডি যোগ করতে অকার্যকর হবে, তবে যদি অন্যথায় অনুমানের প্রয়োজন হয় তবে এটি ব্যবহার করা যেতে পারে নির্বিশেষে অস্তিত্ব।)
কেস 2 : সিরিয়ালযুক্ত ডেটা বা ব্যবহারকারীর কাছে প্রদর্শিত হবে এমন ডেটা নিয়ে কাজ করা। তারিখ অবজেক্টের চেয়ে স্ট্রিং "1999-12-30" হিসাবে ব্যবহার করার মতো (যা সতর্ক না হলে টাইমজোন বাগ বা সংযোজন সিরিয়ালের জটিলতা সৃষ্টি করতে পারে)। অথবা আপনি জানেন আপনি কি করছেন।
- এটা সম্ভবত ঠিক আছে। সাবধান থাকুন যে কোনও বিন্দুর স্ট্রিং না রয়েছে "।" আপনার স্যানিটাইজড ইনপুট টুকরাগুলিতে।
আপনি যদি এই উত্তরটি সারাক্ষণ ব্যবহার করে এবং স্ট্রিং এবং অ্যারের মধ্যে পিছনে রূপান্তরিত করে নিজেকে খুঁজে পান তবে আপনার খারাপ অবস্থা হতে পারে এবং একটি বিকল্প বিবেচনা করা উচিত।
এখানে একটি মার্জিত ওয়ান-লাইনার যা অন্যান্য সমাধানের চেয়ে 10x ছোট:
function index(obj,i) {return obj[i]}
'a.b.etc'.split('.').reduce(index, obj)
[সম্পাদনা করুন] বা ইসমাস্ক্রিপ্ট 6 এ:
'a.b.etc'.split('.').reduce((o,i)=>o[i], obj)
(আমি মনে করি না যে অন্যদের মতো এটি সর্বদা খারাপ বলে মনে হয় এটি যেমন হয় (যদিও এটি সাধারণত হয়) তবে তবুও এই লোকেরা সন্তুষ্ট হবে যে এই পদ্ধতিটি বুদ্ধিমান ব্যবহার করে না The উপরেরটি obj.a.b.etcদেওয়া objএবং স্ট্রিংটি খুঁজে পাবে "a.b.etc"))
reduceECMA-262 স্ট্যান্ডার্ড (5 তম সংস্করণ) থাকা সত্ত্বেও যারা এখনও ব্যবহার করতে ভয় পান তাদের প্রতিক্রিয়া হিসাবে , এখানে একটি দুই-লাইন পুনরাবৃত্তিমূলক বাস্তবায়ন দেওয়া হয়েছে:
function multiIndex(obj,is) { // obj,['1','2','3'] -> ((obj['1'])['2'])['3']
return is.length ? multiIndex(obj[is[0]],is.slice(1)) : obj
}
function pathIndex(obj,is) { // obj,'1.2.3' -> multiIndex(obj,['1','2','3'])
return multiIndex(obj,is.split('.'))
}
pathIndex('a.b.etc')
জেএস সংকলক যে অপটিমাইজেশনগুলি করছে তার উপর নির্ভর করে আপনি নিশ্চিত করতে পারেন যে কোনও পদ্ধতিতে নিয়মিত পদ্ধতিগুলি (কোনও ক্লোজার, অবজেক্ট বা গ্লোবাল নেমস্পেসে রেখে) কোনও নেস্টেড ফাংশন প্রতিটি কলটিতে পুনরায় সংজ্ঞায়িত করা হয় না।
সম্পাদনা করুন :
মন্তব্যে একটি আকর্ষণীয় প্রশ্নের উত্তর দিতে:
আপনি কিভাবে এটি একটি সেটারে পরিণত করবেন? মানগুলি কেবল পথ দিয়েই ফেরত নয়, ফাংশনে কোনও নতুন মান প্রেরণ করা হলে সেগুলি সেট করাও হবে? - সোয়াডার জুন 28:42 এ
(sideenote: দুর্ভাগ্যক্রমে কোনও সেটারের সাথে কোনও জিনিস ফেরত দিতে পারবেন না, কারণ এটি কলিং কনভেনশন লঙ্ঘন করবে; মন্তব্যকারী মনে করছেন পরিবর্তে কোনও সাধারণ সেটার-শৈলীর ফাংশনটি করার মতো পার্শ্ব-প্রতিক্রিয়া সহ উল্লেখ index(obj,"a.b.etc", value)করছেন obj.a.b.etc = value))
reduceস্টাইল সত্যিই যে উপযুক্ত নয়, কিন্তু আমরা recursive বাস্তবায়ন পরিবর্তন করতে পারেন:
function index(obj,is, value) {
if (typeof is == 'string')
return index(obj,is.split('.'), value);
else if (is.length==1 && value!==undefined)
return obj[is[0]] = value;
else if (is.length==0)
return obj;
else
return index(obj[is[0]],is.slice(1), value);
}
ডেমো:
> obj = {a:{b:{etc:5}}}
> index(obj,'a.b.etc')
5
> index(obj,['a','b','etc']) #works with both strings and lists
5
> index(obj,'a.b.etc', 123) #setter-mode - third argument (possibly poor form)
123
> index(obj,'a.b.etc')
123
... যদিও ব্যক্তিগতভাবে আমি পৃথক ফাংশন করার পরামর্শ দিই setIndex(...)। আমি একটি পক্ষের নোটে শেষ করতে চাই যে প্রশ্নের মূল পোজারটি (উচিত?) .splitস্ট্রিংয়ের পরিবর্তে সূচকগুলির অ্যারেগুলি (যা তারা পেতে পারে) নিয়ে কাজ করতে পারে ; যদিও কোনও সুবিধামতনের কার্যক্রমে সাধারণত কিছুই ভুল হয় না।
একজন মন্তব্যকারী জিজ্ঞাসা করলেন:
অ্যারে সম্পর্কে কি? "আব [4] .সিডি [1] [2] [3]" এর মতো কিছু? -AlexS
জাভাস্ক্রিপ্ট একটি খুব অদ্ভুত ভাষা; সাধারণ অবজেক্টগুলিতে কেবল তাদের সম্পত্তি কী হিসাবে স্ট্রিং থাকতে পারে, উদাহরণস্বরূপ যদি যদি xজেনেরিক কোনও জিনিস ছিল x={}তবে x[1]তা হয়ে উঠবে x["1"]... আপনি সেই অধিকারটি পড়েন ... হ্যাঁ ...
জাভাস্ক্রিপ্ট অ্যারেগুলি (যা তারা নিজেরাই বস্তুর উদাহরণ) আপনার পছন্দ মতো কিছু করতে পারলেও পূর্ণসংখ্যা কীগুলি বিশেষত উত্সাহ দেয় x=[]; x["puppy"]=5;।
তবে সাধারণভাবে (এবং এর ব্যতিক্রম রয়েছে), x["somestring"]===x.somestring(যখন এটি অনুমোদিত; আপনি করতে পারবেন না x.123)।
(মনে রাখবেন যে আপনি জেএস সংকলকটি ব্যবহার করছেন তা বেছে নিতে পারে, সম্ভবত এটি সাইনার উপস্থাপনাগুলিতে সংকলন করতে পারে যদি এটি প্রমাণ করে যে এটি অনুমান লঙ্ঘন করবে না))
সুতরাং আপনার প্রশ্নের উত্তর নির্ভর করবে আপনি এই বিষয়গুলি কেবলমাত্র পূর্ণসংখ্যা গ্রহণ করবেন কিনা (আপনার সমস্যার ডোমেনে সীমাবদ্ধতার কারণে) বা না তা নির্ভর করে। ধরা যাক না। তারপরে একটি বৈধ এক্সপ্রেশন হ'ল বেস শনাক্তকারী প্লাস কিছু .identifierএস প্লাস কিছু ["stringindex"]এস a
এটি তখন সমান হবে a["b"][4]["c"]["d"][1][2][3], যদিও আমাদের সম্ভবত সমর্থন করা উচিত a.b["c\"validjsstringliteral"][3]। একটি বৈধ স্ট্রিং আক্ষরিক পার্স কীভাবে করতে হয় তা দেখতে আপনাকে স্ট্রিং লিটারালগুলির একমাস্ক্রিপ্ট ব্যাকরণ বিভাগটি পরীক্ষা করতে হবে। প্রযুক্তিগতভাবে আপনিও পরীক্ষা করতে চান (আমার প্রথম উত্তরের মতো নয়) এটি aএকটি বৈধ জাভাস্ক্রিপ্ট শনাক্তকারী ।
আপনার প্রশ্নের একটি সরল উত্তর যদিও, যদি আপনার স্ট্রিং কমা বা বন্ধনী থাকে না , শুধু সেটে না দৈর্ঘ্য 1+ অক্ষরের ক্রমের সাথে মেলাতে হতে হবে ,বা [বা ]:
> "abc[4].c.def[1][2][\"gh\"]".match(/[^\]\[.]+/g)
// ^^^ ^ ^ ^^^ ^ ^ ^^^^^
["abc", "4", "c", "def", "1", "2", ""gh""]
যদি আপনার স্ট্রিংগুলিতে পালানোর অক্ষর বা "অক্ষর না থাকে এবং আইডেন্টিফায়ারনামগুলি স্ট্রিংলাইটারালগুলির একটি সাবল্যাংগিউজ (আমার মনে হয় ???) আপনি প্রথমে আপনার বিন্দুগুলিকে [] রূপান্তর করতে পারেন:
> var R=[], demoString="abc[4].c.def[1][2][\"gh\"]";
> for(var match,matcher=/^([^\.\[]+)|\.([^\.\[]+)|\["([^"]+)"\]|\[(\d+)\]/g;
match=matcher.exec(demoString); ) {
R.push(Array.from(match).slice(1).filter(x=>x!==undefined)[0]);
// extremely bad code because js regexes are weird, don't use this
}
> R
["abc", "4", "c", "def", "1", "2", "gh"]
অবশ্যই, সর্বদা সতর্ক থাকুন এবং কখনই আপনার ডেটা বিশ্বাস করবেন না। এটি করার কিছু খারাপ উপায় যা কিছু ব্যবহারের ক্ষেত্রে কার্যকর হতে পারে তার মধ্যে রয়েছে:
// hackish/wrongish; preprocess your string into "a.b.4.c.d.1.2.3", e.g.:
> yourstring.replace(/]/g,"").replace(/\[/g,".").split(".")
"a.b.4.c.d.1.2.3" //use code from before
বিশেষ 2018 সম্পাদনা:
আসুন আমরা পুরো বৃত্তে চলে আসি এবং সর্বাধিক অদক্ষ, ভয়াবহ-ওভারমেটপ্রোগ্র্যামড সমাধানটি করতে পারি যা সিন্টেক্সটিকাল বিশুদ্ধতার হ্যামফিসারির স্বার্থে ... ES6 প্রক্সি অবজেক্টের সাথে! ... আসুন কিছু বৈশিষ্ট্যও সংজ্ঞায়িত করা যাক (imho সূক্ষ্ম এবং বিস্ময়কর তবে) ভুল-লিখিত গ্রন্থাগারগুলি ভেঙে দিতে পারে। আপনি যদি পারফরম্যান্স, স্যানিটি (আপনার বা অন্যদের), আপনার কাজ ইত্যাদির বিষয়ে যত্নশীল হন তবে এটি ব্যবহারের বিষয়ে আপনাকে সম্ভবত সতর্ক হওয়া উচিত
// [1,2,3][-1]==3 (or just use .slice(-1)[0])
if (![1][-1])
Object.defineProperty(Array.prototype, -1, {get() {return this[this.length-1]}}); //credit to caub
// WARNING: THIS XTREME™ RADICAL METHOD IS VERY INEFFICIENT,
// ESPECIALLY IF INDEXING INTO MULTIPLE OBJECTS,
// because you are constantly creating wrapper objects on-the-fly and,
// even worse, going through Proxy i.e. runtime ~reflection, which prevents
// compiler optimization
// Proxy handler to override obj[*]/obj.* and obj[*]=...
var hyperIndexProxyHandler = {
get: function(obj,key, proxy) {
return key.split('.').reduce((o,i)=>o[i], obj);
},
set: function(obj,key,value, proxy) {
var keys = key.split('.');
var beforeLast = keys.slice(0,-1).reduce((o,i)=>o[i], obj);
beforeLast[keys[-1]] = value;
},
has: function(obj,key) {
//etc
}
};
function hyperIndexOf(target) {
return new Proxy(target, hyperIndexProxyHandler);
}
ডেমো:
var obj = {a:{b:{c:1, d:2}}};
console.log("obj is:", JSON.stringify(obj));
var objHyper = hyperIndexOf(obj);
console.log("(proxy override get) objHyper['a.b.c'] is:", objHyper['a.b.c']);
objHyper['a.b.c'] = 3;
console.log("(proxy override set) objHyper['a.b.c']=3, now obj is:", JSON.stringify(obj));
console.log("(behind the scenes) objHyper is:", objHyper);
if (!({}).H)
Object.defineProperties(Object.prototype, {
H: {
get: function() {
return hyperIndexOf(this); // TODO:cache as a non-enumerable property for efficiency?
}
}
});
console.log("(shortcut) obj.H['a.b.c']=4");
obj.H['a.b.c'] = 4;
console.log("(shortcut) obj.H['a.b.c'] is obj['a']['b']['c'] is", obj.H['a.b.c']);
আউটপুট:
আপত্তিটি হ'ল: {"a": {"b": {"c": 1, "d": 2}}}
(প্রক্সি ওভাররাইড পান) Hজেক্ট হাইপার ['এবিসি'] হ'ল: ১
(প্রক্সি ওভাররাইড সেট) objHyper ['abc'] = 3, এখন আপত্তি হ'ল: {"a": {"বি": {"সি": 3, "ডি": 2}}}
(পর্দার আড়ালে) Hজেপ হাইপারটি হ'ল: প্রক্সি {এ: {...}}
(শর্টকাট) obj.H ['abc'] = 4
(শর্টকাট) আপত্তি.এইচ ['এবিসি'] হ'ল আপত্তি ['ক'] ['বি'] ['গ'] হ'ল: ৪
অযোগ্য ধারণা: আপনি ইনপুট আর্গুমেন্টের উপর ভিত্তি করে প্রেরণের জন্য উপরেরটি সংশোধন করতে পারেন; হয় .match(/[^\]\[.]+/g)সমর্থন করার জন্য পদ্ধতিটি ব্যবহার করুন obj['keys'].like[3]['this'], বা যদি instanceof Array, তবে কেবল কোনও অ্যারেটিকে ইনপুট হিসাবে গ্রহণ করুন keys = ['a','b','c']; obj.H[keys]।
পরামর্শ হিসাবে আপনি সম্ভবত একটি 'নরম' NaN- স্টাইল পদ্ধতিতে অপরিবর্তিত সূচকগুলি পরিচালনা করতে চান (উদাহরণস্বরূপ, index({a:{b:{c:...}}}, 'a.x.c')টাইপ এয়াররের পরিবর্তে অপরিজ্ঞাত ফিরে আসা) ...:
1) এটি 1-মাত্রিক সূচক পরিস্থিতিতে ({}) ['উদাহরণস্বরূপ'] == অপরিজ্ঞাত, "আমাদের কোনও ত্রুটি ছুঁড়ে না দিয়ে অপরিবর্তিত হওয়া উচিত" ত্রুটিযুক্ত পরিবর্তনের পরিবর্তে আমাদের ত্রুটি ছুঁড়ে ফেলা উচিত of ত্রুটি "এন-মাত্রিক পরিস্থিতিতে।
2) এই আছে না দৃষ্টিকোণ যে আমরা করছেন থেকে জানার জন্য x['a']['x']['c'], যা উপরোক্ত উদাহরণে একটি TypeError সঙ্গে ব্যর্থ হবে।
এটি বলেছিল, আপনি আপনার হ্রাসকরণের ক্রিয়াটি এর সাথে প্রতিস্থাপন করে এই কাজটি করবেন:
(o,i)=>o===undefined?undefined:o[i], বা
(o,i)=>(o||{})[i]।
(আপনি লুপের জন্য এবং ভাঙ্গা / ফিরে আসার ক্ষেত্রে যখনই পরবর্তী সূচিটি অপরিজ্ঞাত করে রেখেছেন বা আপনি যদি এই জাতীয় ব্যর্থতা যথেষ্ট বিরল বলে আশা করেন তবে চেষ্টা করার চেষ্টা করে আপনি এটিকে আরও দক্ষ করে তুলতে পারেন))
evalদুষ্ট! এটি ব্যবহার করবেন না