javascript - 根据相同的属性名称创建对象数组

标签 javascript jquery json

我有基于 XML 文件生成的表单输入。

我们通过 data-* 在 XML 文件中保留嵌套元素的引用稍后可用于构建对象的属性。例如:

<parent>
 <child>
  <grandchild1>first</grandchild1>
  <grandchild2>second</grandchild2>
 </child>
</parent>

成为

<input type="text" data-nest="parent.child.grandchild1" value="first"/> <input type="text" data-nest="parent.child.grandchild2" value="second"/>

当我们提交表单时,我根据他们的 data-nest 创建了一个对象(带有嵌套对象)属性。上面会变成

parent:{
 child:{
  grandchild1: first,
  grandchild2: second
  }
}

我遇到的问题是在 XML 文件中发现了多个相同的标签,例如

<child>
 <grandchild>first</grandchild>
 <grandchildFriend>firstFriend</grandchildFriend>
</child>
<child>
 <grandchild>second</grandchild>
 <grandchildFriend>secondFriend</grandchildFriend>
</child>

当我创建我的对象时,我希望它能使相同的 data-nest 多次出现。找到值后,它们嵌套在一个数组中以维护不同的值。

在当前设置下,第二次出现的标记会覆盖第一次出现,这是可以理解的。

这是我想要的最终对象结构:

parent:{
 child:[
  {
   grandchild: first,
   grandchildFriend: firstFriend
  }, 
  {
   grandchild: second,
   grandchildFriend: secondFriend
  }
  ]
 }

长话短说

我想将一个对象更改为嵌套对象数组,如果它们具有相同的 data-*。属性

这是一个 fiddle当前代码的工作原理有助于更好地理解。

最佳答案

currentObj[lastKey] = value; 替换为:

if(typeof currentObj[lastKey] === 'undefined') {
    currentObj[lastKey] = value;
} else  {
    if(typeof currentObj[lastKey] !== 'array')
            currentObj[lastKey] = [currentObj[lastKey]];
    currentObj[lastKey].push(value);
}

代码将执行以下操作:如果未设置 currentObj[lastKey],您将一如既往地创建一个元素,否则,如果它已经设置并且是一个字符串,代码会将其转换为数组,然后插入数组 后续(任意数量)元素 最终结果将类似于:

parent:{
...
 grandchild:[
   "first", "second"
  ]
...
 }

编辑 为了得到您要求的格式的结果,您需要做一些更多的编辑,如下所示:

var json = {};

config = {
  set: function(keyValueString) {

    var pair = keyValueString.split('=');

    // left of the = is the key path
    var keyPath = pair[0];

    // right of the = is the value to set
    var value = pair[1];

    // split keyPath into an array of keys
    var keys = keyPath.split('.');
    var key;

    var currentObj = json;

    // loop through all keys in the key path, except the last one.
    // this creates the object structure implied by the key path.
    // we want to do something different on the last iteration.
    for (var i=0; i < keys.length-1; i++) {

      // Get the current key we are looping
      key = keys[i];
      // if the requested level on the current object doesn't exist,
      // make a blank object.
      if (typeof currentObj[key] === 'undefined') {
        currentObj[key] = i === keys.length-2 ? []: {};
      }

      currentObj = currentObj[key];
    }

    // our loop doesn't handle the last key, because that's when we
    // want to set the actual value.
    var lastKey = keys[keys.length-1]

    // set the property of the deepest object to the value.
    var child = {};
    child[lastKey] = value;
    currentObj.push(child);
  }
};

// iterate through all of our inputs, and nest them based off their data-* attribute
$('input').each(function(){
    // set nest = value setup, e.g. parent.child.grandchild = first
  // we then break this 
    var key = $(this).attr('data-nest') + '=' + $(this).val();
  config.set(key);
});

// as a bonus - this is how I went about breaking multiple values within a single input into an array
function traverseObject(object){
  // iterate through the object
  for (var i in object){


    // if the next key exists, run again
    if(object[i] !== null && typeof(object[i])=="object"){
      traverseObject(object[i]);
    } else {
    var value = [object[i]];
     // if the value contains a comma
    if(value.toString().indexOf(',') > -1){
      // set the *nested* key to the 
      // value as an array by splitting at the commas
      object[i] =value.toString().split(',').filter(function(el){
        // remove the extra entry after splitting
        return el.length != 0;
      });
    }
    }
  }
}

traverseObject(json);

$('#test').on('click', function(){
    console.log(json)
});

关于javascript - 根据相同的属性名称创建对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47328345/

相关文章:

javascript - 如何使用HTML5文件API读取预先指定的文件?

javascript - 由于ajax代码而导致404错误?

javascript - 清除后间隔开始两次

json - 内部 JSON 结构与 Decodable 方法冲突

javascript - 单击后添加带有输入字段的子项,如树

javascript - 无法从 watchpack-chokidar2 :fsevents 访问 NPM CI 错误绑定(bind)

c# - 如何从 C# 字典创建 JSON(类似于 PHP)

java - 如何在json和java中创建子项,以及如何在javascript中获取子项的值?

jquery - css 过渡不起作用

javascript - 用 php 内容刷新一个 div