У меня есть массив, и я хочу выбрать 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}.....]
но возвращает только все объекты со значением последних элементов массива.
Вы можете использовать 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);
Проблема с вашим кодом в том, что вы мутируете одну временную температуру объекта и нажимаете ее 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;
}, {}));
}
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
для создания этого нового объекта.