如何建立一个像另一个对象的对象?

时间:2019-06-20 12:26:10

标签: javascript jquery

有一些输入。我已经从这些输入的值生成了一个对象。所以,我生成的对象是这样的:

var generate_fields = {
  name: "Mike",
  email: "mike@gmail.com",
  gender: "1",
  hobby: ["travel", "movie"]
}

有一个参考对象:

var ref_obj = {
    personal_information: {
      name: null,
      password: null,
      gender: null
  },
  business_information: {
    email: null,
    id: null,
  },
  special_information: {
    hobby: null,
    achievement: null
  }
}

我需要使用generate_fields之类的对象(例如参考对象ref_obj)来创建新对象。因此,新对象将是:

var custom_obj = {
    personal_information: {
     name: "Mike",  
     gender: "1",
  },
  business_information: {
    email: "mike@gmail.com",
  },
  special_information: {
    hobby: ["travel", "movie"]
  }
}

如何使用custom_objgenerate_fields制作ref_obj

演示:

var ref_obj = {
	personal_information: {
  	name: null,
    password: null,
    gender: null
  },
  business_information: {
  	email: null,
    id: null,
  },
  special_information: {
  	hobby: null,
    achievement: null
  }
}

//console.log(ref_obj);

$('form').submit(function(event) { 
	event.preventDefault();
  var generated_fields = {};
  $(this).find('input, select').not('input[name=submit]').each(function() {
  	generated_fields[this.name] = $(this).val();
  });
  console.log(generated_fields);
});
.form-group {
  margin-bottom: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<form>
  <div class="form-group">
    <laberl>Name: </laberl>
    <input type="text" name="name" id="name" placeholder="Name" />
  </div>
  <div class="form-group">
    <label>Email:</label>
    <input type="text" name="email" id="email" placeholder="Email" />
  </div>
  <div class="form-group">
    <label>Gender:</label>
    <select name="gender" id="gender">
      <option value="1">Male</option>
      <option value="2">Female</option>
      <option value="2">Other</option>
    </select>
  </div>
  <div class="form-group">
    <label>Hobbies:</label>
    <select name="hobby" id="hobby" multiple>
      <option value="books">Reading books</option>
      <option value="travel">Travelling</option>
      <option value="movie">Movie</option>
    </select>
  </div>
  <input type="submit" name="submit" value="submit" />
</form>

3 个答案:

答案 0 :(得分:1)

我建议您使用通用解决方案reduce + forEach。让我尝试描述我的方法。首先,您应该遍历generate_fields数组以确定根级别字段,然后必须遍历每个字段并检查原始对象是否包含相同的属性

var a1 = {
  name: "Mike",
  email: "mike@gmail.com",
  gender: "1",
  hobby: ["travel", "movie"]
}

var a2 = {
    personal_information: {
      name: null,
      password: null,
      gender: null
  },
  business_information: {
    email: null,
    id: null,
  },
  special_information: {
    hobby: null,
    achievement: null
  }
}

const arr = Object.keys(a2).reduce((a, key) => {
	Object.keys(a2[key]).forEach(value => {
		if(a1.hasOwnProperty(value)){
			a[key] = a[key] || {};
			a[key][value] = a1[value];
		}	
	});
	return a;
}, {});

console.log(arr);

答案 1 :(得分:0)

  1. 这是一个没有递归的简单解决方案。注意开关/外壳部分。您必须根据指定将值放入每个属性中。这是最好且最易读的方法,但前提是您事先知道这些字段。对于大型或动态对象,建议不要使用其他.reduce.forEach答案。

  2. 注意,我将这一行更改为:var generated_fields = ref_obj;。如果要创建多个对象,则可能需要使用var generated_fields = {...ref_obj};来获取对象的副本。

  3. 您的第一个<label>的键入错误为<laberl>

var ref_obj = {
	personal_information: { name: null, password: null, gender: null },
  business_information: { email: null, id: null, },
  special_information: { hobby: null, achievement: null }
}

$('form').submit(function(event) { 
	event.preventDefault();
  var generated_fields = ref_obj;
  $(this).find('input, select').not('input[name=submit]').each(function() {
  
    switch (this.name) {
      case 'name':
      case 'password':
      case 'gender':
  	    generated_fields.personal_information[this.name] = $(this).val(); break;
      case 'email':
      case 'id':
        generated_fields.business_information[this.name] = $(this).val(); break;
      case 'achievement':
      case 'hobby':
  	    generated_fields.special_information[this.name] = $(this).val(); break;
    }
    
  });
  console.log(generated_fields);
});
.form-group {
  margin-bottom: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<form>
  <div class="form-group">
    <label>Name: </label>
    <input type="text" name="name" id="name" placeholder="Name" />
  </div>
  <div class="form-group">
    <label>Email:</label>
    <input type="text" name="email" id="email" placeholder="Email" />
  </div>
  <div class="form-group">
    <label>Gender:</label>
    <select name="gender" id="gender">
      <option value="1">Male</option>
      <option value="2">Female</option>
      <option value="2">Other</option>
    </select>
  </div>
  <div class="form-group">
    <label>Hobbies:</label>
    <select name="hobby" id="hobby" multiple>
      <option value="books">Reading books</option>
      <option value="travel">Travelling</option>
      <option value="movie">Movie</option>
    </select>
  </div>
  <input type="submit" name="submit" value="submit" />
</form>

答案 2 :(得分:0)

这是我对您问题的一般解决方案。

基本上,我已经复制了“空”项目,并使用了递归函数将值注入其中。

var generate_fields = {
  name: "Mike", email: "mike@gmail.com",
  gender: "1", hobby: ["travel", "movie"]
};

var ref_obj = {
  personal_information: { name: null, password: null, gender: null },
  business_information: { email: null, id: null},
  special_information:  { hobby: null, achievement: null }
};


// First, create an exact duplicate of ref_obj
var ans = {...ref_obj};

function isObject(obj) {
  return obj != null && obj.constructor.name === "Object";
}

function copyProperty(obj, name, val) {
  for (let property in obj) {
    if (!obj.hasOwnProperty(property)) continue;
    
    if (isObject(obj[property])) {
      // The recursive case
      copyProperty(obj[property], name, val);
    }
    else if (property === name) { // Note that obj[property] isn't an object
      // Inject the property
      obj[property] = val;
    }
  }
  
  return obj;
}

// Iterate the generate_fields object's properties, and copy each of them to 'ans'
for (let property in generate_fields) {
  if (!generate_fields.hasOwnProperty(property)) continue;
  ans = copyProperty(ans, property, generate_fields[property]);
}

console.log(ans);