স্ট্রিং পাথ দ্বারা নেস্টেড জাভাস্ক্রিপ্ট অবজেক্ট এবং অ্যারে অ্যাক্সেস করা


454

আমার এই জাতীয় ডেটা স্ট্রাকচার রয়েছে:

var someObject = {
    'part1' : {
        'name': 'Part 1',
        'size': '20',
        'qty' : '50'
    },
    'part2' : {
        'name': 'Part 2',
        'size': '15',
        'qty' : '60'
    },
    'part3' : [
        {
            'name': 'Part 3A',
            'size': '10',
            'qty' : '20'
        }, {
            'name': 'Part 3B',
            'size': '5',
            'qty' : '20'
        }, {
            'name': 'Part 3C',
            'size': '7.5',
            'qty' : '20'
        }
    ]
};

এবং আমি এই ভেরিয়েবলটি ব্যবহার করে ডেটা অ্যাক্সেস করতে চাই:

var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";

part1name someObject.part1.nameএর মান দিয়ে ভরাট করা উচিত যা "অংশ 1" 1 অংশ 2 পরিমাণে একই জিনিস যা 60 দিয়ে পূর্ণ।

খাঁটি জাভাস্ক্রিপ্ট বা জ্যাকুয়ারি দিয়ে এটি অর্জন করার উপায় আছে কি?


নিশ্চিত না আপনি এখানে কি জিজ্ঞাসা করছেন? আপনি part1.name জিজ্ঞাসা করতে সক্ষম হতে চান এবং "part1.name" পাঠ্যটি ফিরে পেয়েছেন? অথবা আপনি part1.name এর মধ্যে সঞ্চিত মান পেতে একটি উপায় চান?
বনিটি

তোমার মত করছেন চেষ্টা করেছি var part1name = someObject.part1name;`
রাফায়

1
@ বনিটি: আমি কিছুঅবজেক্ট.পার্ট ১.নামটি জিজ্ঞাসা করতে চাই এবং এর মানটি ফিরিয়ে দিতে চাই ("পার্ট 1")। যাইহোক, আমি চাই ক্যোরিটি (আমি এটিকে "কী" বলেছি) একটি ভেরিয়েবল 'পার্ট1 নেমে' সংরক্ষণ করতে চাই। আপনার উত্তর দেওয়ার জন্য ধন্যবাদ. @ 3নিগমা: আমি অবশ্যই করেছি। তবে তা আমার উদ্দেশ্য নয়। জবাবের জন্য ধন্যবাদ.
কোমারুলোহ

1
সদৃশ উত্তরে আমি ফায়রের উত্তর পছন্দ করি স্ট্যাকওভারফ্লো.com
স্টিভ ব্ল্যাক

উত্তর:


520

আমি ইতিমধ্যে আমার মতো কিছু অনুরূপ কোডের ভিত্তিতে এটি তৈরি করেছি, এটি কাজ করে বলে মনে হচ্ছে:

Object.byString = function(o, s) {
    s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
    s = s.replace(/^\./, '');           // strip a leading dot
    var a = s.split('.');
    for (var i = 0, n = a.length; i < n; ++i) {
        var k = a[i];
        if (k in o) {
            o = o[k];
        } else {
            return;
        }
    }
    return o;
}

ব্যবহারের ::

Object.byString(someObj, 'part3[0].name');

একটি কাজের ডেমো দেখুন http://jsfiddle.net/alnitak/hEsys/

কিছু সম্পাদনা করে লক্ষ্য করেছেন যে এই কোডটি এমন স্ট্রিং পাস করলে ত্রুটি ছুঁড়ে ফেলা হবে যেখানে বাম-সর্বাধিক সূচকগুলি বস্তুর মধ্যে সঠিকভাবে নেস্টেড এন্ট্রির সাথে মিল রাখে না। এটি একটি বৈধ উদ্বেগ, তবে আইএমএইচও try / catchএই ফাংশনটি নিঃশব্দে undefinedকোনও অবৈধ সূচকের জন্য ফিরে আসার চেয়ে কল করার সময় একটি ব্লকের সাথে সবচেয়ে ভাল সম্বোধন করে ।


19
এটি সুন্দরভাবে কাজ করে। নোড প্যাকেজ হিসাবে মোড়ক করে এটি ইন্টারনেটে অবদান রাখুন।
t3dodson

14
@ t3dodson আমি সবেমাত্র করেছি: github.com/capaj/object-resolve-path ঠিক মনে রাখবেন যে আপনার সম্পত্তির নাম নিজেই '[]' অন্তর্ভুক্ত থাকলে এটি সুন্দর হয় না। রেজেক্স এটি 'এর সাথে প্রতিস্থাপন করবে। এবং এটি প্রত্যাশার মতো কাজ করে না
ক্যাপাজ

20
দুর্দান্ত জিনিস; লডাশ লাইব্রেরি ব্যবহার করে, আপনিও এটি করতে পারেন:_.get(object, nestedPropertyString);
ian

17
এটি সম্ভবত মন্তব্যের সাগরে নষ্ট হয়ে যাবে, তবে আপনি যদি এমন কোনও সম্পত্তি আবিষ্কার করার চেষ্টা করেন যা অস্তিত্বহীন থাকে তবে এটির ত্রুটি। তাই 'part3[0].name.iDontExist'। সমস্যার সমাধানের oমধ্যে কোনও অবজেক্ট কিনা তা দেখার জন্য একটি চেক যোগ করা if in। (আপনি কীভাবে এটি সম্পর্কে যান তা আপ আপনার উপর নির্ভরশীল)। আপডেট হওয়া ফ্রেড
ste2425

2
এতো সোনা। আমাদের একটি কনফিগার ভিত্তিক অ্যাপ্লিকেশন রয়েছে এবং এটি দুর্দান্ত সহায়ক! ধন্যবাদ!
খ্রিস্টান এস্পেরার

182

এটি আমিই সমাধানটি ব্যবহার করি:

function resolve(path, obj=self, separator='.') {
    var properties = Array.isArray(path) ? path : path.split(separator)
    return properties.reduce((prev, curr) => prev && prev[curr], obj)
}

ব্যবহারের উদাহরণ:

// accessing property path on global scope
resolve("document.body.style.width")
// or
resolve("style.width", document.body)

// accessing array indexes
// (someObject has been defined in the question)
resolve("part3.0.size", someObject) // returns '10'

// accessing non-existent properties
// returns undefined when intermediate properties are not defined:
resolve('properties.that.do.not.exist', {hello:'world'})

// accessing properties with unusual keys by changing the separator
var obj = { object: { 'a.property.name.with.periods': 42 } }
resolve('object->a.property.name.with.periods', obj, '->') // returns 42

// accessing properties with unusual keys by passing a property name array
resolve(['object', 'a.property.name.with.periods'], obj) // returns 42

সীমাবদ্ধতা:

  • []অ্যারে সূচকগুলির জন্য বন্ধনী ( ) ব্যবহার করতে পারবেন না - যদিও বিচ্ছেদী টোকেনের মধ্যে অ্যারে সূচকগুলি নির্দিষ্ট করে (উদাহরণস্বরূপ, .) উপরে উল্লিখিত হিসাবে ঠিকঠাক কাজ করে।

7
হ্রাস ব্যবহার করা একটি দুর্দান্ত সমাধান ( _.reduce()আন্ডারস্কোর বা লড্যাশ লাইব্রেরি থেকেও একটি ব্যবহার করতে পারেন )
Alp

3
আমি মনে করি selfসম্ভবত এখানে অপরিজ্ঞাত। মানে this?
প্ল্যাটিনাম আজুর

2
পথে পথে মান নির্ধারণের জন্য আমার পরিপূরক এখানে রয়েছে: পেস্টবিন.
com

1
যে কেউ টাইপস্ক্রিপ্ট এ কিভাবে পোর্ট করতে জানেন?
অ্যাডাম প্লোচার 14

1
@ এসসি 1000 টি ভাল ধারণা। বেশিরভাগ ব্রাউজারগুলিতে ডিফল্ট প্যারামিটারগুলি উপলব্ধ হওয়ার আগে এই উত্তরটি লেখা হয়েছিল। গ্লোবাল অবজেক্টটিকে ডিফল্ট হিসাবে উল্লেখ করা ইচ্ছাকৃত হওয়ায় আমি এটি "ফাংশন রিলিজ (পথ, অবজেক্ট = স্ব)" এ আপডেট করব।
স্পিগগ

179

এটি এখন লোডাশ ব্যবহার করে সমর্থিত _.get(obj, property)Https://lodash.com/docs#get দেখুন

দস্তাবেজ থেকে উদাহরণ:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// → 3

_.get(object, ['a', '0', 'b', 'c']);
// → 3

_.get(object, 'a.b.c', 'default');
// → 'default'

9
এটি একমাত্র গ্রহণযোগ্য উত্তর হওয়া উচিত, কারণ ডট এবং বন্ধনী উভয়ের জন্যই এটিই একমাত্র কাজ করে এবং এটি যখন ব্যর্থ হয় না, তখন যখন আমাদের পথে []] একটি কীয়ের স্ট্রিং থাকে।
ক্যাপাজ

7
এই. এছাড়াও, এটি সমর্থন করে_.set(...)
জোশ সি

যদি আপত্তি না পাওয়া যায় তবে কী হবে?
DDave

@ ডিডভে যদি অবজেক্ট হিসাবে মানটি নির্ধারিত হয় বা কোনও অবজেক্ট _.getনা হয়ে থাকে তবে সরবরাহকৃত অবজেক্টে কোনও কী না পাওয়া গেলে একই আচরণ দেখাবে। যেমন _.get(null, "foo") -> undefined, _.get(null, "foo", "bar") -> "bar"। তবে এই আচরণটি ডক্সে সংজ্ঞায়িত করা হয়নি সুতরাং পরিবর্তনের সাপেক্ষে।
ইয়ান ওয়াকার-স্পারবার

5
@ কপাজ তুমি কিদিন? এবং কে না চায় / লোডাশ ব্যবহার করতে পারে?
আন্দ্রে ফিগুয়েরেদো

74

ES6 : ভ্যানিলা জেএসে কেবল একটি লাইন (ত্রুটি দেওয়ার পরিবর্তে যদি এটি খুঁজে না পায় তবে এটি বাতিল হয়):

'path.string'.split('.').reduce((p,c)=>p&&p[c]||null, MyOBJ)

বা উদাহরণ:

'a.b.c'.split('.').reduce((p,c)=>p&&p[c]||null, {a:{b:{c:1}}})

ফাংশনটি ব্যবহারের জন্য প্রস্তুত যা মিথ্যা, 0 এবং নেতিবাচক সংখ্যাকেও স্বীকৃতি দেয় এবং ডিফল্ট মানগুলি প্যারামিটার হিসাবে স্বীকার করে:

const resolvePath = (object, path, defaultValue) => path
   .split('.')
   .reduce((o, p) => o ? o[p] : defaultValue, object)

ব্যবহারের উদাহরণ:

resolvePath(window,'document.body') => <body>
resolvePath(window,'document.body.xyz') => undefined
resolvePath(window,'document.body.xyz', null) => null
resolvePath(window,'document.body.xyz', 1) => 1

বোনাস :

একটি পথ নির্ধারণ করতে (@ রব-গর্ডন দ্বারা অনুরোধ করা) আপনি ব্যবহার করতে পারেন:

const setPath = (object, path, value) => path
   .split('.')
   .reduce((o,p,i) => o[p] = path.split('.').length === ++i ? value : o[p] || {}, object)

উদাহরণ:

let myVar = {}
setPath(myVar, 'a.b.c', 42) => 42
console.log(myVar) => {a: {b: {c: 42}}}

[] এর সাথে অ্যারে অ্যাক্সেস করুন :

const resolvePath = (object, path, defaultValue) => path
   .split(/[\.\[\]\'\"]/)
   .filter(p => p)
   .reduce((o, p) => o ? o[p] : defaultValue, object)

উদাহরণ:

const myVar = {a:{b:[{c:1}]}}
resolvePath(myVar,'a.b[0].c') => 1
resolvePath(myVar,'a["b"][\'0\'].c') => 1

2
আমি এই কৌশল পছন্দ। এটি সত্যিই অগোছালো তবে আমি এই কৌশলটি অ্যাসাইনমেন্টের জন্য ব্যবহার করতে চেয়েছিলাম। let o = {a:{b:{c:1}}}; let str = 'a.b.c'; str.split('.').splice(0, str.split('.').length - 1).reduce((p,c)=>p&&p[c]||null, o)[str.split('.').slice(-1)] = "some new value";
রব-গর্ডন

1
আমি ব্যবহার করার ব্যাপারে মত কমাতে কিন্তু আপনার যুক্তিবিজ্ঞান জন্য বন্ধ মনে হয় 0, undefinedএবং nullমান। পরিবর্তে {a:{b:{c:0}}}ফিরে । সম্ভবত স্পষ্টভাবে নাল বা অপরিজ্ঞাত জন্য পরীক্ষা করা এই সমস্যাগুলি পরিষ্কার করবে। null0(p,c)=>p === undefined || p === null ? undefined : p[c]
স্মুজমাইকু

হাই @ সুমুজমাইকু, "0", 'অপরিজ্ঞাত' এবং 'নাল' এর জন্য সঠিকভাবে "ব্যবহারের জন্য প্রস্তুত" ফাংশনটি ফিরে আসছি, আমি ঠিক কনসোলটিতে পরীক্ষা করেছি: রেজাল্টপথ ({a: {b: {c: 0}}}, ' abc ', নাল) => 0; এটি একাধিক চেক এড়াতে মূল্যের পরিবর্তে কীটি উপস্থিত রয়েছে কিনা তা পরীক্ষা করে
দেখায়

এখানে ডিফল্টভ্যালু কাজ করেনি, Reflect.has(o, k) ? ...(ES6 রিফ্লেক.হাস ) ব্যবহার করে যদিও কাজ করেছে
আন্দ্রে

setPathসর্বশেষ নির্বাচকের প্রথম উপস্থিতিতে মান নির্ধারণ করবে। পরিবর্তে উদাহরণস্বরূপ let o = {}; setPath(o, 'a.a', 0)ফলাফল । একটি সমাধানের জন্য এই পোস্টটি দেখুন । {a: 0}{a: {a: 0}}
pkfm

62

আপনাকে নিজেই স্ট্রিংটি পার্স করতে হবে:

function getProperty(obj, prop) {
    var parts = prop.split('.');

    if (Array.isArray(parts)) {
        var last = parts.pop(),
        l = parts.length,
        i = 1,
        current = parts[0];

        while((obj = obj[current]) && i < l) {
            current = parts[i];
            i++;
        }

        if(obj) {
            return obj[last];
        }
    } else {
        throw 'parts is not valid array';
    }
}

এটির জন্য আপনাকে বিন্দু চিহ্নিতকরণ সহ অ্যারে সূচকগুলিও সংজ্ঞায়িত করতে হবে:

var part3name1 = "part3.0.name";

এটি পার্সিংকে আরও সহজ করে তোলে।

ডেমো


@ ফেলিক্স ক্লিংং: আপনার সমাধান আমাকে যা প্রয়োজন তা সরবরাহ করে। এবং আমি আপনাকে এর জন্য অনেক ধন্যবাদ। তবে অ্যালনিটকও বিভিন্ন উপায়ে সরবরাহ করে এবং মনে হয় এটি কাজ করে। যেহেতু আমি কেবল একটি উত্তর চয়ন করতে পারি, তাই আমি আলনিটাক উত্তরটি বেছে নেব। এমন নয় যে তার সমাধান আপনার চেয়ে ভাল বা এরকম কিছু। যাইহোক, আপনার দেওয়া সমাধান এবং প্রচেষ্টার আমি সত্যই প্রশংসা করি।
কোমারুলোহ

1
@ কুমারুলোহ: ওহ আমি ভেবেছিলাম আপনি নিজের প্রশ্নে সর্বদা ভোটের উত্তর দিতে পারবেন .... যাইহোক আমি কম-বেশি ঠাট্টা করছিলাম, আমার বেশি খ্যাতির দরকার নেই;) শুভ কোডিং!
ফেলিক্স ক্লিং

1
@ ফেলিক্স ক্লিং: আপনার ভোট দেওয়ার জন্য কমপক্ষে 15 খ্যাতি লাগবে। :) আমি বিশ্বাস করি যে 69k + দিয়ে আপনার বেশি খ্যাতির দরকার নেই। ধন্যবাদ
কোমারুলোহ

@ ফেলিক্স এফডব্লিউআইডাব্লু - []সিনট্যাক্স থেকে সম্পত্তি সিনট্যাক্সে রূপান্তর করা বেশ তুচ্ছ।
Alnitak

4
আপনি যদি সময় লুপটি পরিবর্তন করেন while (l > 0 && (obj = obj[current]) && i < l)তবে এই কোডটি বিন্দু ছাড়াই স্ট্রিংয়ের জন্য কাজ করে।
Snea

39

বস্তুর ভিতরে অ্যারে / অ্যারেগুলির জন্যও কাজ করে। অবৈধ মানগুলির বিরুদ্ধে প্রতিরক্ষামূলক।

/**
 * Retrieve nested item from object/array
 * @param {Object|Array} obj
 * @param {String} path dot separated
 * @param {*} def default value ( if result undefined )
 * @returns {*}
 */
function path(obj, path, def){
    var i, len;

    for(i = 0,path = path.split('.'), len = path.length; i < len; i++){
        if(!obj || typeof obj !== 'object') return def;
        obj = obj[path[i]];
    }

    if(obj === undefined) return def;
    return obj;
}

//////////////////////////
//         TEST         //
//////////////////////////

var arr = [true, {'sp ace': true}, true]

var obj = {
  'sp ace': true,
  arr: arr,
  nested: {'dotted.str.ing': true},
  arr3: arr
}

shouldThrow(`path(obj, "arr.0")`);
shouldBeDefined(`path(obj, "arr[0]")`);
shouldBeEqualToNumber(`path(obj, "arr.length")`, 3);
shouldBeTrue(`path(obj, "sp ace")`);
shouldBeEqualToString(`path(obj, "none.existed.prop", "fallback")`, "fallback");
shouldBeTrue(`path(obj, "nested['dotted.str.ing'])`);
<script src="https://cdn.rawgit.com/coderek/e7b30bac7634a50ad8fd/raw/174b6634c8f57aa8aac0716c5b7b2a7098e03584/js-test.js"></script>


10
ধন্যবাদ এটি সেরা এবং সর্বাধিক পারফরম্যান্স উত্তর - jsfiddle.net/Jw8XB/1
ডমিনিক

@ নিঃশেষিত, আমি জোর দিয়ে বলতে চাই যে পথগুলির বিন্দুগুলির সাথে আইটেমগুলি পৃথক করা উচিত। ধনুর্বন্ধনী কাজ করবে না। অর্থাৎ অ্যারেতে প্রথম আইটেমটি অ্যাক্সেস করতে "0.sp ace" ব্যবহার করুন।
TheZver

26

ইওল ব্যবহার করে:

var part1name = eval("someObject.part1.name");

ত্রুটি অনির্ধারিত ফিরে মোড়ানো

function path(obj, path) {
    try {
        return eval("obj." + path);
    } catch(e) {
        return undefined;
    }
}

http://jsfiddle.net/shanimal/b3xTw/

Alফলের শক্তি চালিত করার সময় দয়া করে সাধারণ জ্ঞান এবং সতর্কতা ব্যবহার করুন। এটি কিছুটা হালকা সাবারের মতো, যদি আপনি এটি চালু করেন তবে 90% সুযোগ রয়েছে আপনি একটি অঙ্গ কাটাবেন। এটি সবার জন্য নয়।


7
প্রত্যাশিত হওয়া বা না করা একটি ভাল ধারণা সম্পত্তি স্ট্রিং ডেটা কোথা থেকে আসছে তার উপর নির্ভর করে। আমি সন্দেহ করি যে হ্যাকাররা একটি স্ট্যাটিক "var p = 'abc'; eval (p); এর মাধ্যমে ভেঙে যাওয়ার জন্য উদ্বিগ্ন হওয়ার কোনও কারণ আছে;" টাইপ কল। এটি এটির জন্য একটি দুর্দান্ত ধারণা।
জেমস উইলকিনস

17

আপনি সাধারণ নিম্নোক্ত কৌশল দ্বারা কোনও বাহ্যিক জাভাস্ক্রিপ্ট লাইব্রেরি ছাড়াই বিন্দু চিহ্ন সহ একটি গভীর অবজেক্ট সদস্যের মান অর্জন করতে পারবেন:

new Function('_', 'return _.' + path)(obj);

আপনার ক্ষেত্রে কেবল মূল্য part1.nameথেকে মূল্য পেতে someObject:

new Function('_', 'return _.part1.name')(someObject);

এখানে একটি সরল ফিডল ডেমো: https://jsfiddle.net/harishanchu/oq5esowf/


3
ফাংশন ডিপ_ভ্যালু (অবজেক্ট, পাথ) new নতুন ফাংশন রিটার্ন ('ও', 'রিটার্ন ও।' + পাথ) (আপত্তি); }
আর্কেঞ্জেলজিথ

14

এটি সম্ভবত কখনই দিনের আলো দেখবে না ... তবে এখানে এটি যাইহোক।

  1. []সাথে বন্ধনী সিনট্যাক্স প্রতিস্থাপন করুন.
  2. বিভক্ত .চরিত্রের
  3. ফাঁকা স্ট্রিংগুলি সরান
  4. পথটি সন্ধান করুন (অন্যথায় undefined)

// "one liner" (ES6)

const deep_value = (obj, path) => 
  path
    .replace(/\[|\]\.?/g, '.')
    .split('.')
    .filter(s => s)
    .reduce((acc, val) => acc && acc[val], obj);
    
// ... and that's it.

var someObject = {
    'part1' : {
        'name': 'Part 1',
        'size': '20',
        'qty' : '50'
    },
    'part2' : {
        'name': 'Part 2',
        'size': '15',
        'qty' : '60'
    },
    'part3' : [
        {
            'name': 'Part 3A',
            'size': '10',
            'qty' : '20'
        }
        // ...
    ]
};

console.log(deep_value(someObject, "part1.name"));               // Part 1
console.log(deep_value(someObject, "part2.qty"));                // 60
console.log(deep_value(someObject, "part3[0].name"));            // Part 3A


11

এটি লোডাস সহ একটি ওয়ান লাইনার।

const deep = { l1: { l2: { l3: "Hello" } } };
const prop = "l1.l2.l3";
const val = _.reduce(prop.split('.'), function(result, value) { return result ? result[value] : undefined; }, deep);
// val === "Hello"

বা আরও ভাল ...

const val = _.get(deep, prop);

বা ES6 সংস্করণ ডাব্লু / হ্রাস ...

const val = prop.split('.').reduce((r, val) => { return r ? r[val] : undefined; }, deep);

Plunkr


7

আমি মনে করি আপনি এটি চাইছেন:

var part1name = someObject.part1.name;
var part2quantity = someObject.part2.qty;
var part3name1 =  someObject.part3[0].name;

আপনি এই জন্য জিজ্ঞাসা করা যেতে পারে:

var part1name = someObject["part1"]["name"];
var part2quantity = someObject["part2"]["qty"];
var part3name1 =  someObject["part3"][0]["name"];

দুটোই কাজ করবে


অথবা আপনি এই জন্য জিজ্ঞাসা করছেন

var partName = "part1";
var nameStr = "name";

var part1name = someObject[partName][nameStr];

অবশেষে আপনি এই জন্য জিজ্ঞাসা করা যেতে পারে

var partName = "part1.name";

var partBits = partName.split(".");

var part1name = someObject[partBits[0]][partBits[1]];

আমি মনে করি ওপি শেষ সমাধান চাইছে। তবে স্ট্রিংগুলির Splitপদ্ধতি নেই, বরং split
দুরী

আসলে আমি শেষটি জিজ্ঞাসা করছিলাম। পার্টনাম ভেরিয়েবলটি মূল-কাঠামোর মানকে নির্দেশ করে স্ট্রিং দিয়ে পূর্ণ। আপনার সমাধানটি বোধগম্য মনে হয়। তবে আমাকে 4-5 স্তর এবং আরও অনেকের মতো ডেটাতে বর্ধিত গভীরতার জন্য পরিবর্তন করতে হবে। এবং আমি ভাবছি যদি আমি এটির সাথে অ্যারে এবং অবজেক্টটি অভিন্নভাবে আচরণ করতে পারি?
কোমারুলোহ

7

এখানে আমি আরও কিছু উপায়ে দিচ্ছি, যা অনেক দিক থেকে দ্রুত বলে মনে হচ্ছে:

বিকল্প 1: বিভক্ত স্ট্রিং চালু। বা [বা] বা 'বা ", এটি বিপরীত করুন, খালি আইটেমগুলি এড়িয়ে যান।

function getValue(path, origin) {
    if (origin === void 0 || origin === null) origin = self ? self : this;
    if (typeof path !== 'string') path = '' + path;
    var parts = path.split(/\[|\]|\.|'|"/g).reverse(), name; // (why reverse? because it's usually faster to pop off the end of an array)
    while (parts.length) { name=parts.pop(); if (name) origin=origin[name]; }
    return origin;
}

বিকল্প 2 (দ্রুততম ব্যতীত eval): নিম্ন স্তরের চরিত্রের স্ক্যান (কোনও রেগেক্স / স্প্লিট / ইত্যাদি নয়, কেবল একটি দ্রুত চর স্ক্যান)। দ্রষ্টব্য: এইটি সূচকের জন্য উদ্ধৃতি সমর্থন করে না।

function getValue(path, origin) {
    if (origin === void 0 || origin === null) origin = self ? self : this;
    if (typeof path !== 'string') path = '' + path;
    var c = '', pc, i = 0, n = path.length, name = '';
    if (n) while (i<=n) ((c = path[i++]) == '.' || c == '[' || c == ']' || c == void 0) ? (name?(origin = origin[name], name = ''):(pc=='.'||pc=='['||pc==']'&&c==']'?i=n+2:void 0),pc=c) : name += c;
    if (i==n+2) throw "Invalid path: "+path;
    return origin;
} // (around 1,000,000+/- ops/sec)

বিকল্প 3: ( নতুন : বিকল্প 2 উদ্ধৃতি সমর্থন করতে প্রসারিত - কিছুটা ধীর, তবে এখনও দ্রুত)

function getValue(path, origin) {
    if (origin === void 0 || origin === null) origin = self ? self : this;
    if (typeof path !== 'string') path = '' + path;
    var c, pc, i = 0, n = path.length, name = '', q;
    while (i<=n)
        ((c = path[i++]) == '.' || c == '[' || c == ']' || c == "'" || c == '"' || c == void 0) ? (c==q&&path[i]==']'?q='':q?name+=c:name?(origin?origin=origin[name]:i=n+2,name='') : (pc=='['&&(c=='"'||c=="'")?q=c:pc=='.'||pc=='['||pc==']'&&c==']'||pc=='"'||pc=="'"?i=n+2:void 0), pc=c) : name += c;
    if (i==n+2 || name) throw "Invalid path: "+path;
    return origin;
}

জেএসপিফারফ: http://jsperf.com/ways-to-dereferences-a-delimited-property-string/3

"ইভাল (...)" এখনও রাজা যদিও (পারফরম্যান্স অনুযায়ী এটি) is আপনার সম্পত্তির পাথ যদি সরাসরি আপনার নিয়ন্ত্রণে থাকে তবে 'ইভাল' ব্যবহার করে কোনও সমস্যা হওয়া উচিত নয় (বিশেষত গতি পছন্দসই হলে)। যদি "তারের ওপরে" সম্পত্তিটির পথগুলি টানতে ( লাইনে !? Lol: P) থাকে, তবে হ্যাঁ, নিরাপদ থাকতে অন্য কিছু ব্যবহার করুন। কেবল একজন নির্বোধই বলবেন না যে "এভাল" কখনই ব্যবহার করবেন না, কারণ এটি ব্যবহার করার উপযুক্ত কারণ রয়েছে । এছাড়াও, "এটি ডগ ক্রকফোর্ডের জেএসএন পার্সারে ব্যবহৃত হয় ।" যদি ইনপুটটি নিরাপদ থাকে তবে কোনও সমস্যা নেই। সঠিক কাজের জন্য সঠিক সরঞ্জামটি ব্যবহার করুন, এটিই।


6

AngularJS

স্পিগের অ্যাপ্রোচটি খুব ঝরঝরে এবং পরিষ্কার, যদিও স্ট্রিং পাথ দিয়ে অ্যাংুলারজেএস-স্কোপ বৈশিষ্ট্যগুলি অ্যাক্সেসের সমাধান অনুসন্ধান করার সময় আমি এই উত্তরটি পেয়েছি এবং এটি কিছুটা পরিবর্তন করে কাজটি করে:

$scope.resolve = function( path, obj ) {
    return path.split('.').reduce( function( prev, curr ) {
        return prev[curr];
    }, obj || this );
}

আপনার রুট কন্ট্রোলারে কেবল এই ফাংশনটি রাখুন এবং এটির মতো কোনও শিশু সুযোগ ব্যবহার করুন:

$scope.resolve( 'path.to.any.object.in.scope')


5

কেবলমাত্র, যে কেউ 2017 বা তার পরে এই প্রশ্নটি দেখেছেন এবং সহজেই মনে রাখার সহজ উপায় খুঁজছেন, জাভাস্ক্রিপ্টে নেস্টেড অবজেক্টগুলিতে অ্যাক্সেস করার বিষয়ে একটি বিস্তৃত ব্লগ পোস্ট এখানে রয়েছে ছাড়াই

সংজ্ঞায়িত ত্রুটির সম্পত্তি 'ফু' পড়তে পারে না

অ্যারে হ্রাস ব্যবহার করে নেস্টেড অবজেক্টগুলিতে অ্যাক্সেস করুন

আসুন এই উদাহরণ কাঠামো নেওয়া যাক

const user = {
    id: 101,
    email: 'jack@dev.com',
    personalInfo: {
        name: 'Jack',
        address: [{
            line1: 'westwish st',
            line2: 'washmasher',
            city: 'wallas',
            state: 'WX'
        }]
    }
}

নেস্টেড অ্যারে অ্যাক্সেস করতে সক্ষম হতে, আপনি নিজের অ্যারে হ্রাস ব্যবহার লিখতে পারেন।

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);

// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'address', 0, 'city']);
// this will return the city from the first address item.

এখানে একটি দুর্দান্ত টাইপ হ্যান্ডলিং ন্যূনতম গ্রন্থাগার টাইপও রয়েছে যা আপনার জন্য এই সব করে।

টাইপ সহ, আপনার কোডটি দেখতে এইরকম হবে

const city = t(user, 'personalInfo.address[0].city').safeObject;

দাবি অস্বীকার: আমি এই প্যাকেজের লেখক।


3

স্ট্রিং পাথ দিয়ে সমস্ত ক্রিয়াকলাপ করার জন্য আমি এখনও কোনও প্যাকেজ পাইনি, সুতরাং আমি নিজের দ্রুত ছোট প্যাকেজটি লিখে শেষ করেছি যা সন্নিবেশ (), ((ডিফল্ট রিটার্ন সহ)), সেট () সেট এবং মুছে ফেলতে সহায়তা করে ) অপারেশন।

আপনি বিন্দু চিহ্নিতকরণ, বন্ধনী, সংখ্যা সূচক, স্ট্রিং নম্বর বৈশিষ্ট্য এবং অ-শব্দের অক্ষর সহ কীগুলি ব্যবহার করতে পারেন। নীচে সাধারণ ব্যবহার:

> var jsocrud = require('jsocrud');

...

// Get (Read) ---
> var obj = {
>     foo: [
>         {
>             'key w/ non-word chars': 'bar'
>         }
>     ]
> };
undefined

> jsocrud.get(obj, '.foo[0]["key w/ non-word chars"]');
'bar'

https://www.npmjs.com/package/jsocrud

https://github.com/vertical-knowledge/jsocrud


3
/**
 * Access a deep value inside a object 
 * Works by passing a path like "foo.bar", also works with nested arrays like "foo[0][1].baz"
 * @author Victor B. https://gist.github.com/victornpb/4c7882c1b9d36292308e
 * Unit tests: http://jsfiddle.net/Victornpb/0u1qygrh/
 */
function getDeepVal(obj, path) {
    if (typeof obj === "undefined" || obj === null) return;
    path = path.split(/[\.\[\]\"\']{1,2}/);
    for (var i = 0, l = path.length; i < l; i++) {
        if (path[i] === "") continue;
        obj = obj[path[i]];
        if (typeof obj === "undefined" || obj === null) return;
    }
    return obj;
}

সঙ্গে কাজ করে

getDeepVal(obj,'foo.bar')
getDeepVal(obj,'foo.1.bar')
getDeepVal(obj,'foo[0].baz')
getDeepVal(obj,'foo[1][2]')
getDeepVal(obj,"foo['bar'].baz")
getDeepVal(obj,"foo['bar']['baz']")
getDeepVal(obj,"foo.bar.0.baz[1]['2']['w'].aaa[\"f\"].bb")

3

সরল ফাংশন, স্ট্রিং বা অ্যারে পাথের জন্য মঞ্জুরি দেয়।

function get(obj, path) {
  if(typeof path === 'string') path = path.split('.');

  if(path.length === 0) return obj;
  return get(obj[path[0]], path.slice(1));
}

const obj = {a: {b: {c: 'foo'}}};

console.log(get(obj, 'a.b.c')); //foo

অথবা

console.log(get(obj, ['a', 'b', 'c'])); //foo

আপনি যদি উত্তর হিসাবে কোড পোস্ট করতে চলেছেন তবে কোডটি কেন প্রশ্নের উত্তর দেয় তা দয়া করে ব্যাখ্যা করুন ।
টাইসন টি।


2

হ্রাস করা ভাল, আমি বিস্মিত কেউই প্রত্যেকের জন্য ব্যবহৃত হয় না:

function valueForKeyPath(obj, path){
        const keys = path.split('.');
        keys.forEach((key)=> obj = obj[key]);
        return obj;
    };

পরীক্ষা


এমনকি আপত্তি [কী] আসলে আছে কিনা তা আপনি পরীক্ষা করছেন না। এটি অবিশ্বাস্য।
কার্লস আলকোলেয়া

ডিফল্ট জেএস দ্বারা কার্লস অ্যালকোলেয়া কোন বস্তুর কী উপস্থিত আছে কিনা তা যাচাই করবে না: a.b.cযদি bআপনার অবজেক্টে কোনও সম্পত্তি না থাকে তবে একটি ব্যতিক্রম উত্থাপন করবে । আপনার যদি চুপচাপ ভুল কীপথটি খারিজ করে দেওয়ার কিছু প্রয়োজন হয় (যা আমি প্রস্তাব দিই না), আপনি এখনও এইটির সাথে ফোরইচ প্রতিস্থাপন করতে পারেনkeys.forEach((key)=> obj = (obj||{})[key]);
ফ্ল্যাভিয়ান ভলকেন

আমি এটির মাধ্যমে এমন একটি বস্তু চালাই যা একটি কোঁকড়ানো ধনুর্বন্ধনী অনুপস্থিত ছিল, আমার খারাপ :)
কার্লস অ্যালকোলেয়া

1

সবেমাত্র একই প্রশ্ন ছিল এবং সফলভাবে https://npmjs.org/package/tea-properties ব্যবহার করেছে যা setবস্তু / অ্যারেগুলিকে নেস্ট করেছে:

পাওয়া:

var o = {
  prop: {
    arr: [
      {foo: 'bar'}
    ]
  }
};

var properties = require('tea-properties');
var value = properties.get(o, 'prop.arr[0].foo');

assert(value, 'bar'); // true

সেট:

var o = {};

var properties = require('tea-properties');
properties.set(o, 'prop.arr[0].foo', 'bar');

assert(o.prop.arr[0].foo, 'bar'); // true

"এই মডিউলটি বন্ধ করে দেওয়া হয়েছে। ছাইজ / প্যাথওয়াল ব্যবহার করুন।"
প্যাট্রিক ফিশার

1

@ ওয়েবজয়ের উত্তরে অনুপ্রাণিত: https://stackoverflow.com/a/46008856/4110122

আমি এই ফাংশনটি তৈরি করেছিলাম যা আপনি এটিতে অবজেক্টের কোনও মান / সেট / আনসেট করতে ব্যবহার করতে পারেন

function Object_Manager(obj, Path, value, Action) 
{
    try
    {
        if(Array.isArray(Path) == false)
        {
            Path = [Path];
        }

        let level = 0;
        var Return_Value;
        Path.reduce((a, b)=>{
            level++;
            if (level === Path.length)
            {
                if(Action === 'Set')
                {
                    a[b] = value;
                    return value;
                }
                else if(Action === 'Get')
                {
                    Return_Value = a[b];
                }
                else if(Action === 'Unset')
                {
                    delete a[b];
                }
            } 
            else 
            {
                return a[b];
            }
        }, obj);
        return Return_Value;
    }

    catch(err)
    {
        console.error(err);
        return obj;
    }
}

এটি ব্যবহার করতে:

 // Set
 Object_Manager(Obj,[Level1,Level2,Level3],New_Value, 'Set');

 // Get
 Object_Manager(Obj,[Level1,Level2,Level3],'', 'Get');

 // Unset
 Object_Manager(Obj,[Level1,Level2,Level3],'', 'Unset');

1

আমি প্রতিক্রিয়া সহ অনলাইন শপ বিকাশ করছি। জমা দেওয়ার সময় মূল অবস্থাটি আপডেট করার জন্য আমি অনুলিপিযুক্ত রাষ্ট্রের অবজেক্টে মানগুলি পরিবর্তন করার চেষ্টা করেছি। উপরের উদাহরণগুলি আমার পক্ষে কাজ করে নি, কারণ তাদের বেশিরভাগ অনুলিপি করা কপিরাইট অবজেক্টের কাঠামোকে পরিবর্তন করে। গভীর নেস্টেড অবজেক্ট প্রোপার্টিগুলির মান অ্যাক্সেস এবং পরিবর্তন করার জন্য আমি ফাংশনের কার্যকারী উদাহরণটি পেয়েছি: https://lowrey.me/create-an-object-by-path-in-javascript-2/ এখানে এটি রয়েছে:

const createPath = (obj, path, value = null) => {
  path = typeof path === 'string' ? path.split('.') : path;
  let current = obj;
  while (path.length > 1) {
    const [head, ...tail] = path;
    path = tail;
    if (current[head] === undefined) {
      current[head] = {};
    }
    current = current[head];
  }
  current[path[0]] = value;
  return obj;
};

1

আলনিটকের উত্তরের ভিত্তিতে

আমি একটি চেকের মধ্যে পলিফিলটি আবৃত করে ফাংশনটিকে একক শৃঙ্খলাবদ্ধভাবে হ্রাস করেছি।

if (Object.byPath === undefined) {
  Object.byPath = (obj, path) => path
    .replace(/\[(\w+)\]/g, '.$1')
    .replace(/^\./, '')
    .split(/\./g)
    .reduce((ref, key) => key in ref ? ref[key] : ref, obj)
}

const data = {
  foo: {
    bar: [{
      baz: 1
    }]
  }
}

console.log(Object.byPath(data, 'foo.bar[0].baz'))


0

কোডিংয়ের সময় আপনি যদি না জেনে আলাদা আলাদা নেস্টেড কী অ্যাক্সেস করতে চান তবে (এগুলি সম্বোধন করা তুচ্ছ হবে) আপনি অ্যারে নোটেশন অ্যাকসেসরটি ব্যবহার করতে পারেন:

var part1name = someObject['part1']['name'];
var part2quantity = someObject['part2']['qty'];
var part3name1 =  someObject['part3'][0]['name'];

এগুলি ডট সংকেত অ্যাকসেসরের সমতুল্য এবং রানটাইমে পৃথক হতে পারে, উদাহরণস্বরূপ:

var part = 'part1';
var property = 'name';

var part1name = someObject[part][property];

সমতুল্য

var part1name = someObject['part1']['name'];

অথবা

var part1name = someObject.part1.name;

আমি আশা করি এই ঠিকানাটি আপনার প্রশ্ন ...

সম্পাদনা

আমি একটি স্ট্রিং ব্যবহার করবে না xPath কেমন mantain করতে কোয়েরি একটি বস্তু মান অ্যাক্সেস করতে। যেহেতু আপনার ক্যোয়ারীটি বিশ্লেষণ করতে এবং মানটি পুনরুদ্ধার করতে আপনাকে একটি ফাংশন কল করতে হবে আমি অন্য পথ অনুসরণ করব (নয়:

var part1name = function(){ return this.part1.name; }
var part2quantity = function() { return this['part2']['qty']; }
var part3name1 =  function() { return this.part3[0]['name'];}

// usage: part1name.apply(someObject);

বা, যদি আপনি প্রয়োগ পদ্ধতির সাথে অস্বস্তি হন

var part1name = function(obj){ return obj.part1.name; }
var part2quantity = function(obj) { return obj['part2']['qty']; }
var part3name1 =  function(obj) { return obj.part3[0]['name'];}

// usage: part1name(someObject);

ফাংশনগুলি সংক্ষিপ্ত, পরিষ্কার, দোভাষী আপনার জন্য সিনট্যাক্স ত্রুটি ইত্যাদির জন্য তাদের পরীক্ষা করুন।

যাইহোক, আমি অনুভব করি যে সঠিক সময়ে করা একটি সহজ কার্যভার যথেষ্ট হবে ...


মজাদার. তবে আমার ক্ষেত্রে, যখন আমি পার্টনামনেম নির্ধারণ করি তখন সামোবজেক্টটি আরম্ভ হবে। আমি কেবল কাঠামো জানি। এই কারণেই স্ট্রাকচারটি বর্ণনা করতে আমি স্ট্রিং ব্যবহার করি। এবং আশা করছি যে এটি কোনও অজেক্ট থেকে আমার ডেটা জিজ্ঞাসা করতে এটি ব্যবহার করতে সক্ষম হবেন। আপনার চিন্তা ভাগ করে নেওয়ার জন্য ধন্যবাদ। :)
কোমারুলোহ

@ কোমারুলোহ: আমি মনে করি আপনি লিখবেন যে আপনি যখন নিজের ভেরিয়েবলগুলি তৈরি করেন তখন অবজেক্টটি আরম্ভ হয় নি। যেভাবে আমি পয়েন্টটি পাই না, আপনি কেন যথাযথ সময়ে অ্যাসাইনমেন্টটি করতে পারবেন না?
Eineki

কিছু না উল্লেখ করার জন্য দুঃখিত যে কোনওরকম এখনও শুরু হয়নি yet কারণ হিসাবে হিসাবে, SomeObject ওয়েব পরিষেবা মাধ্যমে আনা হয়। এবং আমি শিরোনামের একটি অ্যারে রাখতে চাই যা পার্ট1 নেম, পার্ট 2 কিটি ইত্যাদি থাকে যাতে আমি শিরোনাম অ্যারের মধ্য দিয়ে লুপ করতে পারি এবং পার্টনেম মানের উপর ভিত্তি করে আমি যে মানটি পেতে চাইতাম সেটিকে 'কী' / কোনও অবজেক্টের পাথ হিসাবে পেতে পারি।
কোমারুলোহ

0

এখানে সমাধানগুলি কেবল গভীরভাবে নেস্টেড কীগুলি অ্যাক্সেসের জন্য। অ্যাক্সেস, যুক্ত, সংশোধন এবং মুছে ফেলার জন্য আমার একটি দরকার। এটিই আমি নিয়ে এসেছি:

var deepAccessObject = function(object, path_to_key, type_of_function, value){
    switch(type_of_function){
        //Add key/modify key
        case 0: 
            if(path_to_key.length === 1){
                if(value)
                    object[path_to_key[0]] = value;
                return object[path_to_key[0]];
            }else{
                if(object[path_to_key[0]])
                    return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
                else
                    object[path_to_key[0]] = {};
            }
            break;
        //delete key
        case 1:
            if(path_to_key.length === 1){
                delete object[path_to_key[0]];
                return true;
            }else{
                if(object[path_to_key[0]])
                    return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
                else
                    return false;
            }
            break;
        default:
            console.log("Wrong type of function");
    }
};
  • path_to_key: একটি অ্যারে পথ। আপনি এটি দ্বারা প্রতিস্থাপন করতে পারেন string_path.split(".")
  • type_of_function: অ্যাক্সেসের জন্য 0 (এতে কোনও মান পাস করবেন না value), 0 যোগ এবং পরিবর্তন করার জন্য। মোছার জন্য 1।

0

আলনিটকের জবাব বন্ধ করে দেওয়া:

if(!Object.prototype.byString){
  //NEW byString which can update values
Object.prototype.byString = function(s, v, o) {
  var _o = o || this;
      s = s.replace(/\[(\w+)\]/g, '.$1'); // CONVERT INDEXES TO PROPERTIES
      s = s.replace(/^\./, ''); // STRIP A LEADING DOT
      var a = s.split('.'); //ARRAY OF STRINGS SPLIT BY '.'
      for (var i = 0; i < a.length; ++i) {//LOOP OVER ARRAY OF STRINGS
          var k = a[i];
          if (k in _o) {//LOOP THROUGH OBJECT KEYS
              if(_o.hasOwnProperty(k)){//USE ONLY KEYS WE CREATED
                if(v !== undefined){//IF WE HAVE A NEW VALUE PARAM
                  if(i === a.length -1){//IF IT'S THE LAST IN THE ARRAY
                    _o[k] = v;
                  }
                }
                _o = _o[k];//NO NEW VALUE SO JUST RETURN THE CURRENT VALUE
              }
          } else {
              return;
          }
      }
      return _o;
  };

}

এটি আপনাকে পাশাপাশি একটি মান সেট করতে দেয়!

আমি একজন তৈরি করেছি npm প্যাকেজ এবং GitHub এই সঙ্গে পাশাপাশি


0

স্ট্রিংয়ের পরিবর্তে একটি অ্যারে নেস্টেড অবজেক্টস এবং অ্যারেগুলি অ্যাড্রেসিং ব্যবহার করা যেতে পারে যেমন: ["my_field", "another_field", 0, "last_field", 10]

এই অ্যারে উপস্থাপনার ভিত্তিতে একটি ক্ষেত্র পরিবর্তন করবে এমন একটি উদাহরণ এখানে। আমি নিয়ন্ত্রিত ইনপুট ক্ষেত্রগুলির জন্য react.js তে এরকম কিছু ব্যবহার করছি যা নেস্টেড স্ট্রাকচারের অবস্থাকে পরিবর্তন করে।

let state = {
        test: "test_value",
        nested: {
            level1: "level1 value"
        },
        arr: [1, 2, 3],
        nested_arr: {
            arr: ["buh", "bah", "foo"]
        }
    }

function handleChange(value, fields) {
    let update_field = state;
    for(var i = 0; i < fields.length - 1; i++){
        update_field = update_field[fields[i]];
    }
    update_field[fields[fields.length-1]] = value;
}

handleChange("update", ["test"]);
handleChange("update_nested", ["nested","level1"]);
handleChange(100, ["arr",0]);
handleChange('changed_foo', ["nested_arr", "arr", 3]);
console.log(state);

0

পূর্ববর্তী উত্তরের ভিত্তিতে, আমি একটি ফাংশন তৈরি করেছি যা বন্ধনীগুলিও পরিচালনা করতে পারে। কিন্তু বিভক্ত হওয়ার কারণে তাদের ভিতরে কোনও বিন্দু নেই।

function get(obj, str) {
  return str.split(/\.|\[/g).map(function(crumb) {
    return crumb.replace(/\]$/, '').trim().replace(/^(["'])((?:(?!\1)[^\\]|\\.)*?)\1$/, (match, quote, str) => str.replace(/\\(\\)?/g, "$1"));
  }).reduce(function(obj, prop) {
    return obj ? obj[prop] : undefined;
  }, obj);
}

0

// (IE9+) Two steps

var pathString = "[0]['property'].others[3].next['final']";
var obj = [{
  property: {
    others: [1, 2, 3, {
      next: {
        final: "SUCCESS"
      }
    }]
  }
}];

// Turn string to path array
var pathArray = pathString
    .replace(/\[["']?([\w]+)["']?\]/g,".$1")
    .split(".")
    .splice(1);

// Add object prototype method
Object.prototype.path = function (path) {
  try {
    return [this].concat(path).reduce(function (f, l) {
      return f[l];
    });
  } catch (e) {
    console.error(e);
  }
};

// usage
console.log(obj.path(pathArray));
console.log(obj.path([0,"doesNotExist"]));


0

নিয়ে কাজ করা Underscore'র propertyবা propertyOf:

var test = {
  foo: {
    bar: {
      baz: 'hello'
    }
  }
}
var string = 'foo.bar.baz';


// document.write(_.propertyOf(test)(string.split('.')))

document.write(_.property(string.split('.'))(test));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

শুভকামনা ...

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.