从字符串创建JavaScript对象

4

我将尝试创建一个JavaScript函数,使用字符串作为结构来创建对象,并从DOM数据中填充它。

例如,以下字符串可能如下所示:

some.example.here = "hello"
some.example.there = "hi"
other.example = "heyo"

这应该创建这个对象:

{
    some: {
        example: {
            here: "hello",
            there: "hi"
        },
    other: {
        example: "heyo
    }
}

所述数据来自DOM,并在标记为“读取数据到对象”的代码段中加载。数据正常加载,对象结构也正常设置,但数据未放入数据字段。

以下是该函数的代码:

function getDataFromElement(element) {
  obj = {};
  $(element)
    .find("[data-value]")
    .each(function() {
      // create object node
      valueObj = {};
      currentValueObj = valueObj;
      $.each($(this).attr("data-value").split("."), function(i, objpath) {
        currentValueObj[objpath] = {};
        currentValueObj = currentValueObj[objpath];
      });

      // read data into object
      if($(this).is("[data-putvalue]") && $(this).attr("data-putvalue") != "html") {
        currentValueObj = $(this).attr($(this).attr("data-putvalue"));
      } else {
        currentValueObj = $(this).html();
      }

      console.log(currentValueObj);

      // combine with previous gathered data
      obj = $.extend(true, {}, obj, valueObj);
    });

  return obj;
}

有人知道该怎么做吗?


可以在问题中包含HTML吗?创建stacksnippets,jsfiddle http://jsfiddle.net 来演示吗? - guest271314
currentValueObj = currentValueObj[objpath]; 的目的是什么? - guest271314
通过第二个 for 循环,我试图创建对象结构。因此,该循环遍历字符串的每个元素,使用当前字符串元素名称创建一个新的子元素,并使用 currentValueObj[objpath] = {}; 进入该子元素,以便在下一个循环中创建下一个子元素。 - Lukas Bach
currentValueObj 在每次迭代中都被覆盖了吗?问题中可以包含 html,创建 stacksnippets 来演示吗? - guest271314
4个回答

4
我会这样做:
var createObject = function(model, name, value) {
  var nameParts = name.split("."),
  currentObject = model;
  for (var i in nameParts) {
    var part = nameParts[i];
    if (i == nameParts.length-1) {
      currentObject[part] = value;
      break;
    }
    if (typeof currentObject[part] == "undefined") {
      currentObject[part] = {};
    }
    currentObject = currentObject[part];
  }
};

然后像这样使用它:
var model = {};
createObject(model, "some.example.here", "hello");
createObject(model, "some.example.there", "hi");
createObject(model, "other.example", "heyo");

这将为每个键值对创建不同的模型/对象。 - Nikos M.

3
一些功能实现:

在IT技术方面,有一些常见的功能实现:

const value = 'hello';
'some.example.here'.split('.').reverse().reduce((reduction, segment, index) => {
  const result = {};
  if (index === 0) {                                                                 
    result[segment] = value;
  } else {                                                               
    result[segment] = reduction;
  }

  return result;
}, {})

1
currentTarget 来自哪里? - mindmaster

2

也许这个方案适合您(改编自我的另一个项目,根据需要进行调整和使用): 请注意,该元素的name被视为keyvalue被视为value

function fields2model( $elements, dataModel )
{
    $elements.each(function( ){
        var $el = $(this), 
            name = $el.attr('name'), 
            key, k, i, o, val
        ;

        key = name;

        val = $el.val() || '';

        k = key.split('.'); o = dataModel;
        while ( k.length )
        {
            i = k.shift( );
            if ( k.length ) 
            {
                if ( !o.hasOwnProperty( i ) ) o[ i ] = /^\d+$/.test( k[0] ) ? [ ] : { };
                o = o[ i ];
            }
            else 
            {
                o[ i ] = val;
            }
        }
    });
}

示例用法:

<input name="some.example.here" value="hello" />
<input name="some.example.there" value="hi" />


var model = {};
fields2model($('input,textarea,select'), model);

上述示例元素将生成以下模型:
model = {
some: {
    example: {
        here: "hello",
        there: "hi"
    }
};

1
我在这里尝试了你的函数:https://plnkr.co/edit/NhsnQJs1iYWKUCff2aVU?p=preview,但它没有工作 - 可能是我的错误。你能帮忙吗? - ESP32
我搞定了:https://plnkr.co/edit/EyGmop9CmYO3WAf9odvU Javascript很奇怪 - 不是吗?;-) - ESP32

1

@theFreedomBanana +1

对我来说没问题

const magicFunction = (string, value) =>
  string
    .split('.')
    .reverse()
    .reduce((acc, cur, index) => ({ [cur]: index === 0 ? value : acc }), {});

请不要将“谢谢”作为答案。相反,只需投票支持您认为有帮助的答案。-【来自审核】 - tdy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接