将带点的字符串转换为javascript中访问嵌套对象的指令

Convert string with dots to instructions for accessing nested object in javascript

本文关键字:访问 嵌套 javascript 对象 指令 字符串 转换      更新时间:2023-09-26

我得到一个字符串'hits.hits'和一个名为responses的json对象。该对象包含基于给定字符串路径的我想要的数据。字符串路径根据服务返回的数据而变化。

{
    "hits": {
        "hits": {
            "col": "data",
            "col2": "data",
            "col3": "data"
        }
    }
}

如何将字符串转换为引用指令,以便调用:

var extracted_data = responses.hits.hits; ?注意-人们立即将其标记为副本,但这正是我需要引用对象的方式。我必须使用这种格式来引用对象。

var log = function(val){
  document.write('<pre>' + JSON.stringify(val,null , ' ') + '</pre>');
};
var responses = {
        "hits": {
            "hits": {
                "col": "data",
                "col2": "data",
                "col3": "data"
            }
        }
    }
        
    var extracted_data = responses.hits.hits;
    log(extracted_data);
    var StringToFind = 'hits.hits';
    extracted_data = StringToFind.split('.').reduce(function( t , v ){ return t[v];} , responses);
    
    log(extracted_data);
/**
*
* More complete test case :
*/
// we create a function 
// to extract the data 
// from src 
// according a path
// 
var extractData = function( path , src , splitter){
  var _splitChar = splitter || '.'; 
  
  // we transform the string in array 
  // splitted by the 'splitter'
  var arr = path.split( _splitChar ); 
  
  return arr.reduce(function( transfomed , value ){ 
    return transfomed[value];
  } , src);
  
};
// let try it :
var objectSource = {
   "tags": [
      "anim",
      "tempor",
      "enim",
      "veniam",
      "duis",
      "duis",
      "et"
    ],
    "person" : {
      "isActive": true,
      "payment" : {
         "balance": "$1,945.05",
       },
       "profil" : {
         "picture": "http://placehold.it/32x32",
         "elements" : [
           { "id" : "square" } ,
           { "id" : "circle" } ,
           { "id" : "triangle" } ,
         ]
       },
       "physic" : {
         "age": 24,
         "eyeColor": "green",
         "gender": "female",
      
       },
      "name": "Pauline Madden",
      "company": {
        "name" : "VALPREAL",
      },
      "email": "paulinemadden@valpreal.com",
      "phone": "+1 (888) 515-2346",
      "address": "939 Gerald Court, Nash, Utah, 7374",
     },
};
           
var dataToFind = 'person.name';
log( extractData( dataToFind , objectSource ));
dataToFind = 'person.company.name';
log( extractData( dataToFind , objectSource ));
dataToFind = 'person.profil.elements.2.id';
log( extractData( dataToFind , objectSource ));
dataToFind = 'tags.2';
log( extractData( dataToFind , objectSource ));
           
 /* Try with another splitter charachter */
           
var dataToFind = 'person/name';
log( extractData( dataToFind , objectSource , "/"));
log( extractData( 'person/address' , objectSource , "/"));
log( extractData( 'person/payment/balance' , objectSource , "/"));
log( extractData( 'person.payment.balance' , objectSource ));
           
/******************************************************************
Polyfill
Array.prototype.reduce was added to the ECMA-262 standard in the 5th edition; 
as such it may not be present in all implementations of the standard. 
You can work around this by inserting the following code 
at the beginning of your scripts, allowing use of reduce 
in implementations which do not natively support it.
*******************************************************************/
           
// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
if (!Array.prototype.reduce) {
  Array.prototype.reduce = function(callback /*, initialValue*/) {
    'use strict';
    if (this == null) {
      throw new TypeError('Array.prototype.reduce called on null or undefined');
    }
    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function');
    }
    var t = Object(this), len = t.length >>> 0, k = 0, value;
    if (arguments.length == 2) {
      value = arguments[1];
    } else {
      while (k < len && !(k in t)) {
        k++; 
      }
      if (k >= len) {
        throw new TypeError('Reduce of empty array with no initial value');
      }
      value = t[k++];
    }
    for (; k < len; k++) {
      if (k in t) {
        value = callback(value, t[k], k, t);
      }
    }
    return value;
  };
}
/***************************************************************************/