无法创建对象数组

时间:2018-10-15 17:34:51

标签: javascript arrays object ecmascript-6

我有一个数组,我想选择其3个元素并将其作为单个对象存储在另一个数组中,并再次对数组的每3个元素重复执行相同的过程。这是我的代码如下:

let breakpoints = [
  {name: "from-amonut", value: "100"},
  {name: "to-amonut", value: "200"},
  {name: "gst", value: "10"},
  {name: "from-amonut", value: "200"},
  {name: "to-amonut", value: "300"},
  {name: "gst", value: "20"},
  {name: "from-amonut", value: "300"},
  {name: "to-amonut", value: "400"},
  {name: "gst", value: "30"}
];

let temp = {
  "from_amount": 0,
  "to_amount": 0,
  "gst": 0
};

let formattedBreakpoints = [];

breakpoints.map((v, k) => {
  (v.name == "from-amonut") ? temp.from_amount = v.value: "";
  (v.name == "to-amonut") ? temp.to_amount = v.value: "";
  (v.name == "gst") ? temp.gst = v.value: "";
  ((k + 1) % 3 === 0) ? (formattedBreakpoints.push(temp), console.log(temp)) : "";

});
console.log(formattedBreakpoints);

我期望formattedBreakpoints[{"from_amount":100, "to_amount":200, "gst":10}, {"from_amount":200, "to_amount":300, "gst":20}.....],但只返回具有最后一个数组元素值的所有对象。

3 个答案:

答案 0 :(得分:2)

您可以使用Array.reduce()将所有属性添加到最后一个对象。每当索引(i的3的余数为0时,就会向累加器添加另一个对象。

const breakpoints = [{"name":"from-amonut","value":"100"},{"name":"to-amonut","value":"200"},{"name":"gst","value":"10"},{"name":"from-amonut","value":"200"},{"name":"to-amonut","value":"300"},{"name":"gst","value":"20"},{"name":"from-amonut","value":"300"},{"name":"to-amonut","value":"400"},{"name":"gst","value":"30"}];
        
const result = breakpoints.reduce((r, { name, value }, i) => {
  if(i % 3 === 0) r.push({});
  
  const key = name.replace(/-/g, '_');

  r[r.length - 1][key] = value;
  
  return r;
}, []);

console.log(result);

代码中的问题是temp的重用。由于temp是一个对象,因此将其推入数组,将引用添加到数组,并且不会创建新对象。为防止这种情况,只要您到达最后一个属性,就可以初始化temp。您还应该使用Array.forEach()(对值进行处理),而不要使用Array.map()(根据原始值创建包含项目的新数组)。

const breakpoints = [{"name":"from-amonut","value":"100"},{"name":"to-amonut","value":"200"},{"name":"gst","value":"10"},{"name":"from-amonut","value":"200"},{"name":"to-amonut","value":"300"},{"name":"gst","value":"20"},{"name":"from-amonut","value":"300"},{"name":"to-amonut","value":"400"},{"name":"gst","value":"30"}];

let temp = {};

const formattedBreakpoints = [];

breakpoints.forEach((v, k) => {
  if(v.name == "from-amonut") temp.from_amount = v.value;
  if(v.name == "to-amonut") temp.to_amount = v.value;
  if(v.name == "gst") { // whenever we get to gst, we can push to array, and reset temp
    temp.gst = v.value;
    formattedBreakpoints.push(temp);
    temp = {};
  };
});
console.log(formattedBreakpoints);

答案 1 :(得分:2)

您的代码存在以下问题:正在更改单个对象的温度并将其推入结果数组3次。那么怎么回事:

  1. 您正在创建一个对象
  2. 在map方法中,您要对其进行重复变异,并且每3次迭代后,您都将对此对象的引用设置为结果数组。

此处的关键字是reference。这意味着这是同一对象。例如:

const result = [];
const obj = {};

obj.a = 'a';
result.push(obj); // => result = [{ a: 'a' }]

obj.b = 'b';
result.push(obj); // => result = [{ a: 'a', b: 'b' }, { a: 'a', b: 'b' }]

尝试这种方式:

let formattedBreakpoints = [];
for (let i = 0; i < breakpoints.length; i += 3) {
  const breakPointOptions = breakpoints.slice(i, i + 3);
  formattedBreakpoints.push(breakPointOptions.reduce((result, { name, value }) => {
    result[name] = value;
    return result;
  }, {}));
}

答案 2 :(得分:1)

let breakpoints = [
    			{name: "from-amonut", value: "100"},
    			{name: "to-amonut", value: "200"},
    			{name: "gst", value: "10"},
    			{name: "from-amonut", value: "200"},
    			{name: "to-amonut", value: "300"},
    			{name: "gst", value: "20"},
    			{name: "from-amonut", value: "300"},
    			{name: "to-amonut", value: "400"},
    			{name: "gst", value: "30"}
    		]
    		let temp = {
    			"from_amount" : 0,
    			"to_amount" : 0,
    			"gst" : 0
    		};
    		let formattedBreakpoints = [];
    		breakpoints.map((v, k)=>{
    			(v.name == "from-amonut") ? temp.from_amount = v.value : "";
    			(v.name == "to-amonut") ? temp.to_amount = v.value : "";
    			(v.name == "gst") ? temp.gst = v.value : "";
    			((k + 1) % 3 === 0) ? (formattedBreakpoints.push(temp), temp = {... temp}) : "" ;
    			
    		});
    		console.log(formattedBreakpoints);

由于temp是一个对象,因此您通过引用使用它。因此,您每次按下时都需要创建一个新对象,否则将引用同一对象。因此,我使用temp本身来创建这个新对象。