Reputation: 1900
I have an array and I want to pick 3 of its elements and put store it in another array as a single object and again repeatedly follow the same process on every 3 elements of the array. This is my code below:
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);
I'm expecting formattedBreakpoints
to be [{"from_amount":100, "to_amount":200, "gst":10}, {"from_amount":200, "to_amount":300, "gst":20}.....]
but only returns all the objects with the value of last array elements.
Upvotes: 0
Views: 75
Reputation: 2879
The problem with your code that you are mutating a single object temp and pushing it 3 times to the result array. So what's going on:
Key word here is reference
. That means that this is the same object. For example:
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' }]
Try this way:
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;
}, {}));
}
Upvotes: 2
Reputation: 191976
You can use Array.reduce()
to add all properties to the last object. Whenever the index (i
) remainder from 3 is 0, you add another object to the accumulator.
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);
What's the problem in your code is the reuse of temp
. Since temp is an object, pushing it to the array, adds the reference to the array, and doesn't create a new object. To prevent that, you can init temp
whenever you get to the last property. You should also use Array.forEach()
(do something with value) instead of Array.map()
(create new array with items based on original values).
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);
Upvotes: 2
Reputation: 2358
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);
As temp
is an object you are using it by reference. So you need to create a new object each time you push or else the same object will be referenced. Hence I'm using temp
itself to create this new object.
Upvotes: 1