简体   繁体   English

JavaScript中隐式对象字符串

[英]Covert string to object in javascript

I need to transform a string 我需要转换一个字符串

1. "user.member.staffAddress"
2. "user.something"

to object: 反对:

1. { user: { member: { staffAddress: {} } } }
2. { user: { something: {} } }

Does anyone has an elegant way how to do it? 有谁有优雅的方法呢? It should always be an object in object. 它应该始终是对象中的对象。 The last property should be an empty one. 最后一个属性应为空。

I wrote a utility that I think you will find helpful for this: https://github.com/forms-js/forms-js/blob/master/source/utils/flatten.ts 我编写了一个实用程序,我认为您会对此有所帮助: https : //github.com/forms-js/forms-js/blob/master/source/utils/flatten.ts

Here's the relevant bits. 这是相关的位。 It's written in TypeScript but if you remove the :type annotations, it's valid JavaScript. 它是用TypeScript编写的,但是如果删除:type批注,则它是有效的JavaScript。

/**
 * Writes a value to the location specified by a flattened key and creates nested structure along the way as needed.
 *
 * <p>For example, writing "baz" to the key 'foo.bar' would result in an object <code>{foo: {bar: "baz"}}</code>.
 * Writing 3 to the key 'foo[0].bar' would result in an object <code>{foo: [{bar: 3}]}</code>.
 */
function write(value:any, flattenedKey:string, object:any):void {
  var currentKey:any;
  var keyIndexStart = 0;

  for (var charIndex = 0, length = flattenedKey.length; charIndex < length; charIndex++) {
    var character = flattenedKey.charAt(charIndex);

    switch(character) {
      case '[':
        currentKey = flattenedKey.substring(keyIndexStart, charIndex);

        createPropertyIfMissing_(currentKey, object, Array);
        break;
      case ']':
        currentKey = flattenedKey.substring(keyIndexStart, charIndex);
        currentKey = parseInt(currentKey); // Convert index from string to int

        // Special case where we're targeting this object in the array
        if (charIndex === length - 1) {
          object[currentKey] = value;
        } else {

          // If this is the first time we're accessing this Array key we may need to initialize it.
          if (!object[currentKey] && charIndex < length - 1) {
            switch(flattenedKey.charAt(charIndex + 1)) {
              case '[':
                object[currentKey] = [];
                break;
              case '.':
                object[currentKey] = {};
                break;
            }
          }

          object = object[currentKey];
        }
        break;
      case '.':
        currentKey = flattenedKey.substring(keyIndexStart, charIndex);

        // Don't do anything with empty keys that follow Array indices (e.g. anArray[0].aProp)
        if (currentKey) {
          createPropertyIfMissing_(currentKey, object, Object);
        }
        break;
      default:
        continue; // Continue to iterate...
        break;
    }

    keyIndexStart = charIndex + 1;

    if (currentKey) {
      object = object[currentKey];
    }
  }

  if (keyIndexStart < flattenedKey.length) {
    currentKey = flattenedKey.substring(keyIndexStart, flattenedKey.length);

    object[currentKey] = value;
  }
}

/**
 * Helper method for initializing a missing property.
 *
 * @throws Error if unrecognized property specified
 * @throws Error if property already exists of an incorrect type
 */
function createPropertyIfMissing_(key:string, object:any, propertyType:any):void {
  switch(propertyType) {
    case Array:
      if (!object.hasOwnProperty(key)) {
        object[key] = [];
      } else if (!(object[key] instanceof Array)) {
        throw Error('Property already exists but is not an Array');
      }
      break;
    case Object:
      if (!object.hasOwnProperty(key)) {
        object[key] = {};
      } else if (typeof object[key] !== 'object') {
        throw Error('Property already exists but is not an Object');
      }
      break;
    default:
      throw Error('Unsupported property type');
      break;
  }
}

To be fair, you could also consider a project written specifically for doing this - rather than mine, in which it's only a small portion - which is to say, https://github.com/hughsk/flat 公平地说,您还可以考虑专门为此目的编写的项目-而不是我的项目,在我的项目中只占一小部分-也就是说, https://github.com/hughsk/flat

Iterate and add the properties etc ... 迭代并添加属性等

 function stringToObject(str) { var obj = {}, arr = str.split('.'); (function it(o) { var key = arr.shift(); o[key] = {}; if (arr.length) it(o[key]); }(obj)); return obj; } var obj = stringToObject("user.member.staffAddress"); document.body.innerHTML = JSON.stringify(obj, null, 4); 

A string conversion approach: 字符串转换方法:

var str = 'user.member.staffAddress'
var str_arr = str.split('.')
var obj = JSON.parse(
    '{ "' + str_arr.join('": { "') + '": {}' 
    + Array(str_arr.length+1).join(' }')
)
console.log(obj)
// { "user": { "member": { "staffAddress": {} } } }
  1. Split the string. 分割字符串。
  2. Join elements with ": { " . ": { "连接元素。
  3. Wrap new string with { " and ": {} followed by length number of closing curly braces. { "": {}包装新字符串,后跟右大括号的length
  4. Parse final string as JSON object. 将最终字符串解析为JSON对象。

JSFiddle Demo JSFiddle演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM