#javascript #arrays #javascript-objects
Вопрос:
У меня есть массив объектов Javascript, как показано ниже
const lab = [
{
name: "Lance",
item: "PS",
"3-Aug-21": "117.69",
"4-Aug-21": "120.1",
"5-Aug-21": "122.08",
},
{
name: "Sam",
item: "PS",
"3-Aug-21": "100.14",
"4-Aug-21": "101.2",
"5-Aug-21": "103",
},
{
name: "Vince",
item: "PS",
"3-Aug-21": "12.65",
"4-Aug-21": "13.29",
"5-Aug-21": "13.68",
},
];
Я изменил это, как показано ниже
const labCheck = [
{
id: "Lance",
values: [
{ date: "3-Aug-21", risklevel: "117.69" },
{ date: "4-Aug-21", risklevel: "120.1" },
{ date: "5-Aug-21", risklevel: "122.08" },
],
},
{
id: "Sam",
values: [
{ date: "3-Aug-21", risklevel: "100.14" },
{ date: "4-Aug-21", risklevel: "101.2" },
{ date: "5-Aug-21", risklevel: "103" },
],
},
{
id: "Vince",
values: [
{ date: "3-Aug-21", risklevel: "12.65" },
{ date: "4-Aug-21", risklevel: "13.29" },
{ date: "5-Aug-21", risklevel: "13.68" },
],
},
];
Я попробовал код ниже
const labCheck = lab
.map((d) => d.name)
.map(function (name) {
// console.log(id);
return {
id: name,
values: Object.keys(lab[0])
.slice(2)
.map(function (d, id) {
return {
date: d,
risklevel: lab[id][d],
};
}),
};
});
Кажется, это работает, я понимаю структуру, но значения riskLevel
одинаковы для всех id
, и это неверно.
Я пытался исправить это в течение нескольких дней, но безуспешно. Кто-нибудь может, пожалуйста, помочь?
Ответ №1:
Использование деструктурирования для выделения и переименования свойств, которые нас интересуют, на каждом уровне рефакторинга.
const lab = [{ name: "Lance", item: "PS", "3-Aug-21": "117.69", "4-Aug-21": "120.1", "5-Aug-21": "122.08", }, { name: "Sam", item: "PS", "3-Aug-21": "100.14", "4-Aug-21": "101.2", "5-Aug-21": "103", }, { name: "Vince", item: "PS", "3-Aug-21": "12.65", "4-Aug-21": "13.29", "5-Aug-21": "13.68", },];
const labCheck = lab.map(({ name: id, item, ...values }) => ({
id,
values: Object.entries(values).map(([date, risklevel]) => ({ date, risklevel }))
}));
console.log(labCheck)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Если вам нужно изменить значения в рамках рефакторинга, вы не можете использовать сокращение свойств, но вам нужно будет явно объявить каждое свойство и присвоить соответствующее измененное значение.
const lab = [{ name: "Lance", item: "PS", "3-Aug-21": "117.69", "4-Aug-21": "120.1", "5-Aug-21": "122.08", }, { name: "Sam", item: "PS", "3-Aug-21": "100.14", "4-Aug-21": "101.2", "5-Aug-21": "103", }, { name: "Vince", item: "PS", "3-Aug-21": "12.65", "4-Aug-21": "13.29", "5-Aug-21": "13.68", },];
const labCheck = lab.map(({ name: id, item, ...values }) => ({
id,
values: Object.entries(values).map(([date, risklevel]) => ({
date: new Date(Date.parse(date)), // Date.parse() is not reliable, but used as example here.
risklevel: risklevel
}))
}));
console.log(labCheck)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Комментарии:
1. Сообщество Javascript — это так круто. Я получил 5 ответов в течение 10 минут! Спасибо. Я буду принимать ответ Ника с тех пор, как он был первым (я новичок в JS и не знаю, как оценивать код по другим параметрам). Также проголосуйте за свой ответ.
2. не беспокойтесь, хотя использование
slice()
в этом ответе является хрупким, поскольку порядок ключей не гарантируется. Также изучите назначение деструктуризации, поскольку оно может быть мощным и описательным инструментом.3. обязательно проверю это.
4. Хорошее разрушение
5. @moys Это должен быть приемлемый ответ. Срез небезопасен
Ответ №2:
Проблема в том, что здесь:
Object.keys(lab[0])
Вы ВСЕГДА берете первый элемент массива вместо итерации по ним.
Кроме того, вы объединяете два .map
метода. Когда вы это сделаете, вторая карта получит в качестве входных данных результат предыдущего метода, в вашем случае имя, тем самым потеряв доступ к исходному элементу.
Вы можете использовать:
const lab=[{name:"Lance",item:"PS","3-Aug-21":"117.69","4-Aug-21":"120.1","5-Aug-21":"122.08"},{name:"Sam",item:"PS","3-Aug-21":"100.14","4-Aug-21":"101.2","5-Aug-21":"103"},{name:"Vince",item:"PS","3-Aug-21":"12.65","4-Aug-21":"13.29","5-Aug-21":"13.68"}];
const labCheck = lab.map((item) => {
return {
id: item.name,
values: Object.keys(item)
// The order of the keys is not guaranteed, better not to use .slice() because it could fail on unpredicatable situations
.filter((key) => key !== 'name' amp;amp; key !== 'item')
.map((key) => {
return { date: key, riskLevel: item[key] }
})
}
})
console.log(labCheck)
Комментарии:
1. Лучший ответ имо, должен быть принятым
Ответ №3:
Вы можете сделать что-то вроде этого :
const lab = [
{
name: "Lance",
item: "PS",
"3-Aug-21": "117.69",
"4-Aug-21": "120.1",
"5-Aug-21": "122.08",
},
{
name: "Sam",
item: "PS",
"3-Aug-21": "100.14",
"4-Aug-21": "101.2",
"5-Aug-21": "103",
},
{
name: "Vince",
item: "PS",
"3-Aug-21": "12.65",
"4-Aug-21": "13.29",
"5-Aug-21": "13.68",
},
];
const formattedLab = lab.map((el) => {
const values = Object.entries(el).slice(2);
return {
id: el.name,
values: values.map(value => ({
date: value[0],
riskLevel: value[1]
})),
}
});
console.log(formattedLab);
Комментарии:
1. Большое вам спасибо! Я ломаю голову над этим уже 2 дня!
2. Обратите внимание на приведение к плаванию с использованием унарного плюса. Может быть, они вам нужны как струны?
3. Мне нужен на самом деле уровень риска в виде цифр, так что унарный плюс идеально подходит. Это плюс для этого ответа 🙂
Ответ №4:
map
над Object.entries
, чтобы получить доступ к данным в массиве и вернуть их.
const lab=[{name:"Lance",item:"PS","3-Aug-21":"117.69","4-Aug-21":"120.1","5-Aug-21":"122.08"},{name:"Sam",item:"PS","3-Aug-21":"100.14","4-Aug-21":"101.2","5-Aug-21":"103"},{name:"Vince",item:"PS","3-Aug-21":"12.65","4-Aug-21":"13.29","5-Aug-21":"13.68"}];
// `map` over the array
const out = lab.map(obj => {
// Grab the name, and item, and then everything else
const { name, item, ...rest } = obj;
// `map` over the object entries and for each iteration
// return a new object
const values = Object.entries(rest).map(([key, value]) => {
return { date: key, riskLevel: value };
});
// Return the new array
return { name, values };
});
console.log(out);
Комментарии:
1. Сообщество Javascript — это так круто. Я получил 5 ответов в течение 10 минут! Спасибо. Я буду принимать ответ Ника с тех пор, как он был первым (я новичок в JS и не знаю, как оценивать код по другим параметрам). Также проголосуйте за свой ответ.
Ответ №5:
Это работает для меня:
const labCheck = lab.map((obj, i) => {
const newObj = {id: obj.name, values: []};
Object.keys(lab[i]).slice(2).forEach(date => {
newObj.values.push({
date: date,
risklevel: lab[i][date]
});
})
return newObj;
})