#javascript #node.js #arrays #ecmascript-6
#javascript #node.js #массивы #ecmascript-6
Вопрос:
У меня есть следующий массив объектов.
let arr = [
{
"alerts": {
"bp": {
"diaDiff": -20,
"Notes": null,
"resolveStatus": "0",
"sysDiff": 10
},
"threshold": {
"diaHigh": "110",
"diaLow": "60",
"sysHigh": "150",
"sysLow": "90"
},
"thresholdBpUnit": "mmHg"
},
"measurementDate": 1593934933000,
"actualUserID ": "11111"
},
{
"alerts": {
"bp": {
"diaDiff": -20,
"Notes": null,
"resolveStatus": "0",
"sysDiff": 10
},
"threshold": {
"diaHigh": "110",
"diaLow": "60",
"sysHigh": "150",
"sysLow": "90"
},
"thresholdBpUnit": "mmHg"
},
"measurementDate": 1593934933000,
"actualUserID ": "2222"
},
{
"alerts": {
"bp": {
"diaDiff": 80,
"Notes": null,
"resolveStatus": "0",
"sysDiff": 20
},
"threshold": {
"diaHigh": "120",
"diaLow": "60",
"sysHigh": "140",
"sysLow": "90"
},
"thresholdBpUnit": "mmHg"
},
"measurementDate": 6593934956000,
"actualUserID ": "11111"
},
{
"alerts": {
"bp": {
"diaDiff": 400,
"Notes": null,
"resolveStatus": "0",
"sysDiff": 10
},
"threshold": {
"diaHigh": "170",
"diaLow": "60",
"sysHigh": "190",
"sysLow": "90"
},
"thresholdBpUnit": "mmHg"
},
"measurementDate": 1593934944000,
"actualUserID ": "2222"
},
{
"alerts": {
"bp": {
"diaDiff": 300,
"Notes": null,
"resolveStatus": "0",
"sysDiff": 10
},
"threshold": {
"diaHigh": "570",
"diaLow": "60",
"sysHigh": "190",
"sysLow": "90"
},
"thresholdBpUnit": "mmHg"
},
"measurementDate": 8593934989000,
"actualUserID ": "6666"
}
];
Мне нужно объединить объект массива, имеющий тот же ключ идентификатора пользователя, и ожидает следующего вывода.
let response = {
"success": true,
"data": {
"patient": [
{
"userID": "11111", // I need userID not actualUserID
"bpAlertData": [
{
alerts: { // object },
measurementDate: 1593934933000
},
{
alerts: { // object },
measurementDate: 6593934956000
}
]
},
{
"userID": "22222",
"bpAlertData": [
{
alerts: { // object },
measurementDate: 1593934944000
},
{
alerts: { // object },
measurementDate: 1593934933000
}
]
}
]
},
};
Я попробовал следующее, но застрял с этим.
arr.forEach((item) => {
let filteredData = response.data.patient.filter(patient => patient.userID === item.actualUserID);
if(filteredData.length) {
const existingIndex = response.data.patient.indexOf(filteredData[0]);
response.data.patient[existingIndex].bpAlertData = response.data.patient[existingIndex].bpAlertData.concat(item);
} else {
response.data.patient.push(item);
}
});
console.log(response.data.patient);
Вместо actualUserID я ожидаю userId в ответе. Также как мы можем поместить эти данные в bpAlertData. Итак, может ли кто-нибудь помочь мне с этим, так как я застрял с этим надолго. Любая помощь была бы очень признательна.
Ответ №1:
Вы могли бы сгруппировать с идентификатором и получить массив пациентов.
const
data = [{ alerts: { bp: { diaDiff: -20, Notes: null, resolveStatus: "0", sysDiff: 10 }, threshold: { diaHigh: "110", diaLow: "60", sysHigh: "150", sysLow: "90" }, thresholdBpUnit: "mmHg" }, measurementDate: 1593934933000, actualUserID: "11111" }, { alerts: { bp: { diaDiff: -20, Notes: null, resolveStatus: "0", sysDiff: 10 }, threshold: { diaHigh: "110", diaLow: "60", sysHigh: "150", sysLow: "90" }, thresholdBpUnit: "mmHg" }, measurementDate: 1593934933000, actualUserID: "2222" }, { alerts: { bp: { diaDiff: 80, Notes: null, resolveStatus: "0", sysDiff: 20 }, threshold: { diaHigh: "120", diaLow: "60", sysHigh: "140", sysLow: "90" }, thresholdBpUnit: "mmHg" }, measurementDate: 6593934956000, actualUserID: "11111" }, { alerts: { bp: { diaDiff: 400, Notes: null, resolveStatus: "0", sysDiff: 10 }, threshold: { diaHigh: "170", diaLow: "60", sysHigh: "190", sysLow: "90" }, thresholdBpUnit: "mmHg" }, measurementDate: 1593934944000, actualUserID: "2222" }, { alerts: { bp: { diaDiff: 300, Notes: null, resolveStatus: "0", sysDiff: 10 }, threshold: { diaHigh: "570", diaLow: "60", sysHigh: "190", sysLow: "90" }, thresholdBpUnit: "mmHg" }, measurementDate: 8593934989000, actualUserID: "6666" }],
patient = Object.values(data.reduce((r, { actualUserID: userID, ...o }) => {
if (!r[userID]) r[userID] = { userID, bpAlertData: [] };
r[userID].bpAlertData.push(o);
return r;
}, [])),
response = { success: true, data: { patient } };
console.log(response);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Комментарии:
1. Я не ожидаю, что actualUserID в результате. Итак, как мы можем сделать это лучше?
2. Не могли бы вы сообщить мне, пожалуйста, цель actualUserID: userId ?
3. это переименование деструктурированного свойства: присвоение новым именам переменных
Ответ №2:
Вы можете использовать функцию Array.prototype.reduce
для группировки и функцию Object.values
для извлечения сгруппированных объектов с помощью userID
.
let arr = [ { "alerts": { "bp": { "diaDiff": -20, "Notes": null, "resolveStatus": "0", "sysDiff": 10 }, "threshold": { "diaHigh": "110", "diaLow": "60", "sysHigh": "150", "sysLow": "90" }, "thresholdBpUnit": "mmHg" }, "measurementDate": 1593934933000, "actualUserID": "11111"},{ "alerts": { "bp": { "diaDiff": -20, "Notes": null, "resolveStatus": "0", "sysDiff": 10 }, "threshold": { "diaHigh": "110", "diaLow": "60", "sysHigh": "150", "sysLow": "90" }, "thresholdBpUnit": "mmHg" }, "measurementDate": 1593934933000, "actualUserID": "2222"},{ "alerts": { "bp": { "diaDiff": 80, "Notes": null, "resolveStatus": "0", "sysDiff": 20 }, "threshold": { "diaHigh": "120", "diaLow": "60", "sysHigh": "140", "sysLow": "90" }, "thresholdBpUnit": "mmHg" }, "measurementDate": 6593934956000, "actualUserID": "11111"},{ "alerts": { "bp": { "diaDiff": 400, "Notes": null, "resolveStatus": "0", "sysDiff": 10 }, "threshold": { "diaHigh": "170", "diaLow": "60", "sysHigh": "190", "sysLow": "90" }, "thresholdBpUnit": "mmHg" }, "measurementDate": 1593934944000, "actualUserID": "2222"},{ "alerts": { "bp": { "diaDiff": 300, "Notes": null, "resolveStatus": "0", "sysDiff": 10 }, "threshold": { "diaHigh": "570", "diaLow": "60", "sysHigh": "190", "sysLow": "90" }, "thresholdBpUnit": "mmHg" }, "measurementDate": 8593934989000, "actualUserID": "6666" } ],
obj = { "success": true, "data": {"patient": Object.values(arr.reduce((a, {alerts, measurementDate, actualUserID: userID}) => {
(a[userID] || (a[userID] = {bpAlertData: [], userID})).bpAlertData.push({alerts, measurementDate});
return a;
}, {}))}};
console.log(obj);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Комментарии:
1. Не могли бы вы сообщить мне, почему мы использовали actualUserID: userId внутри метода reduce? Я не понял, в чем дело
2. @Vishnu это называется назначением деструктурирования, я использовал этот способ, потому что a хотел создать объекты с желаемым именем свойства.
Ответ №3:
Подход
Вы могли бы сгруппировать элемент по userId
, а затем манипулировать с помощью этого сгруппированного
const userIdDataMapping = arr.reduce((acc, { actualUserID, ...el }) => {
if (acc[actualUserID] !== undefined) {
acc[actualUserID].push(el)
} else {
acc[actualUserID] = [el]
}
return acc
}, {})
const res = Object.entries(userIdDataMapping).map(([userId, bpAlertData]) => ({
userId,
bpAlertData,
}))
Примечание
{ actualUserID, ...el }
для исключенияactualUserId
из элемента[userId, bpAlertData]
разрушающее назначение
Полный код
let arr = [
{
alerts: {
bp: {
diaDiff: -20,
Notes: null,
resolveStatus: "0",
sysDiff: 10,
},
threshold: {
diaHigh: "110",
diaLow: "60",
sysHigh: "150",
sysLow: "90",
},
thresholdBpUnit: "mmHg",
},
measurementDate: 1593934933000,
actualUserID: "11111",
},
{
alerts: {
bp: {
diaDiff: -20,
Notes: null,
resolveStatus: "0",
sysDiff: 10,
},
threshold: {
diaHigh: "110",
diaLow: "60",
sysHigh: "150",
sysLow: "90",
},
thresholdBpUnit: "mmHg",
},
measurementDate: 1593934933000,
actualUserID: "2222",
},
{
alerts: {
bp: {
diaDiff: 80,
Notes: null,
resolveStatus: "0",
sysDiff: 20,
},
threshold: {
diaHigh: "120",
diaLow: "60",
sysHigh: "140",
sysLow: "90",
},
thresholdBpUnit: "mmHg",
},
measurementDate: 6593934956000,
actualUserID: "11111",
},
{
alerts: {
bp: {
diaDiff: 400,
Notes: null,
resolveStatus: "0",
sysDiff: 10,
},
threshold: {
diaHigh: "170",
diaLow: "60",
sysHigh: "190",
sysLow: "90",
},
thresholdBpUnit: "mmHg",
},
measurementDate: 1593934944000,
actualUserID: "2222",
},
{
alerts: {
bp: {
diaDiff: 300,
Notes: null,
resolveStatus: "0",
sysDiff: 10,
},
threshold: {
diaHigh: "570",
diaLow: "60",
sysHigh: "190",
sysLow: "90",
},
thresholdBpUnit: "mmHg",
},
measurementDate: 8593934989000,
actualUserID: "6666",
},
]
const userIdDataMapping = arr.reduce((acc, { actualUserID, ...el }) => {
if (acc[actualUserID] !== undefined) {
acc[actualUserID].push(el)
} else {
acc[actualUserID] = [el]
}
return acc
}, {})
const res = Object.entries(userIdDataMapping).map(([userId, bpAlertData]) => ({
userId,
bpAlertData,
}))
console.log(res)
Ссылка
Комментарии:
1. Не могли бы вы, пожалуйста, объяснить часть else? acc[actualUserID] = [el] Я не понял, что касается []
2. @Vishnu это инициализация массива с одним элементом, вот
el
3. Можете ли вы дать какую-нибудь ссылку на использование этого? Тем не менее, я в замешательстве относительно обозначения квадратных скобок 🙂
4. @Vishnu: это просто массив developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /…