我正在尝试从后端数据中提取特定字段以准备表格的主体。传入的数据具有以下结构:
[
{
_id: "63056cee252b83f4bc8f97e9",
goals: [
{ title: "Cook" },
{ title: "Budget" }
],
visitEnd: "2022-08-18T00:30:00.000Z",
visitStart: "2022-08-17T21:30:00.000Z",
},
{
_id: "63223586798c6b2658a0d576",
goals: [
{ title: "Cook" },
{ title: "Budget" },
{ title: "Clean" }
],
visitEnd: "2022-09-13T00:30:00.000Z",
visitStart: "2022-09-12T22:00:00.000Z"
},
{
_id: "63542ecfca5bd097a0d9acaf",
goals: [
{ title: "Cook" },
{ title: "Clean" }
],
visitEnd: "2022-10-12T19:00:11.000Z",
visitStart: "2022-10-12T17:00:00.000Z",
}]
由于表格标题是按月/年划分的,因此我使用 lodash 按月对它们进行分组,这让我来到这里:
Object { 7: (2) […], 8: (2) […], 9: (2) […] }
7: Array [ {…}, {…} ]
0: Object { user: "62410a1dcaac9a3d0528de7a", location: "Firm Office in LA", visitStart: "2022-08-17T21:30:00.000Z", … }
1: Object { user: "62410a1dcaac9a3d0528de7a", location: "place", visitStart: "2022-08-11T21:00:57.000Z", … }
length: 2
<prototype>: Array []
8: Array [ {…}, {…} ]
0: Object { user: "62410a1dcaac9a3d0528de7a", location: "Home", visitStart: "2022-09-12T22:00:00.000Z", … }
1: Object { user: "62410a1dcaac9a3d0528de7a", location: "place", visitStart: "2022-09-21T21:00:00.000Z", … }
length: 2
<prototype>: Array []
9: Array [ {…}, {…} ]
0: Object { user: "62410a1dcaac9a3d0528de7a", location: "Home", visitStart: "2022-10-12T17:00:00.000Z", … }
1: Object { user: "62410a1dcaac9a3d0528de7a", location: "place", visitStart: "2022-10-21T21:00:00.000Z", … }
length: 2
但是现在我被卡住了,因为我想隔离目标数组的字段,它在对象中,在每个月的数组中,它包含在一个对象中。我试过玩弄 Object.keys 和地图,然后从这里开始:https://dev.to/flexdinesh/accessing-nested-objects-in-javascript--9m4 came access a function to get deeply nested项目。但我还是把它搞砸了,我的头在旋转,试图弄明白它。我查看了 lodash 的映射和属性,但不确定如何实现给定的嵌套层,我正尝试在 groupBy 对象中的动态命名数组上工作。这是我所在的位置,但我收到错误 i.map is not a function
const sort = groupBy(visits, ({visitEnd})=> new Date(visitEnd).getMonth());
console.log("sort 1: ", sort)
const stage = Object.keys(sort).map((i) => {
{ i.map((el) => getNestedObject(el, ['goals', 'title'])) }
})
console.log("sort 2: ", stage)
我的 javascript 知识很糟糕,这无济于事……
你得到的错误,
i.map
is not a function,意味着变量 i
不是数组。根据您在帖子中提供的数据i
是一个对象。
使用
Object.entries()
与 Object.keys()
迭代排序的月/年数据的结果。
要获得每月的独特目标列表,输出如下:
{
7: ["Cook", "Spend", "Clean"],
8: ["Cook", "Budget", "Clean"],
9: ["Cook", "Budget", "Scrub", "Fold", "Rest", "Wash"]
}
const dataSortedByMoYrObj = {
7: [{
user: "62410a1dcaac9a3d0528de7a",
location: "Firm Office in LA",
visitStart: "2022-08-17T21:30:00.000Z",
goals: [{
title: ""
},
{
title: "Spend"
},
{
title: "Clean"
}
]
},
{
user: "62410a1dcaac9a3d0528de7a",
location: "place",
visitStart: "2022-08-11T21:00:57.000Z",
goals: [{
title: "Cook"
},
{
title: undefined
}
]
}
],
8: [{
user: "62410a1dcaac9a3d0528de7a",
location: "Home",
visitStart: "2022-09-12T22:00:00.000Z",
goals: [{
title: "Cook"
},
{
title: "Budget"
},
{
title: null
}
]
},
{
user: "62410a1dcaac9a3d0528de7a",
location: "place",
visitStart: "2022-09-21T21:00:00.000Z"
}
],
9: [{
user: "62410a1dcaac9a3d0528de7a",
location: "Home",
visitStart: "2022-10-12T17:00:00.000Z",
goals: [{
title: "Cook"
},
{
title: "Budget"
},
{
title: "Scrub"
}
]
},
{
user: "62410a1dcaac9a3d0528de7a",
location: "place",
visitStart: "2022-10-21T21:00:00.000Z",
goals: [{
title: "Fold"
},
{
title: "Rest"
},
{
title: "Wash"
}
]
}
]
};
// 'const getNestedObject' code sourced from:
// https://dev.to/flexdinesh/accessing-nested-objects-in-javascript--9m4
const getNestedObject = (nestedObj, pathArr) => {
return pathArr.reduce((obj, key) =>
(obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}
const goalsByMonthYearObj = {};
Object.entries(dataSortedByMoYrObj).forEach(([month, users]) => {
// 'month' represents the key.
// 'users' is an array of 'user' objects listed for each month.
let goalsByMonth = [];
users.forEach(user => {
const goalsProp = getNestedObject(user, ['goals']);
// Check if the 'goals' property is a valid.
// If 'goals' property is 'null' or 'undefined',
// '!Array.isArray(null)' returns 'true'.
if (!Array.isArray(goalsProp)) {
return;
}
// Convert list of goal objects (e.g. '{title: Budget}')
// to an array using 'goalsProp.map()'.
// Use the 'filter()' method first to remove empty strings
// 'null' and 'undefined' values in the 'title' property.
// https://stackoverflow.com/questions/24806772/how-to-skip-over-an-element-in-map
const goalsArr = goalsProp.filter(goal => goal.title).map(goal => goal.title);
// Concatenate goals array to the existing goals-by-month array.
goalsByMonth = goalsByMonth.concat(goalsArr);
});
// Sort array of goals alphabetically
// https://stackoverflow.com/a/45544166
goalsByMonth.sort((a, b) => a.localeCompare(b));
// Add array of unique goals for each month
// https://stackoverflow.com/questions/1960473/get-all-unique-values-in-a-javascript-array-remove-duplicates
goalsByMonthYearObj[month] = [...new Set(goalsByMonth)];
});
console.log(goalsByMonthYearObj);
(原始代码不像上面的片段那么简洁。)
const goalsByMonthYearObj = {};
// Reference to 'Object.entries()' at:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
for (const [key, value] of Object.entries(dataSortedByMoYrObj)) {
// 'key' represents a month index.
// 'value' contains an array of objects listed for each month index.
//console.log(`${key}: ${value}`);
const goalsByMonth = [];
value.forEach(item => {
// The 'goals' property is only one level deep so
// it's not necessary to use the 'getNestedObject()'
// function.
// For example: const goalsProp = item.goals;
// The function is useful for more deeply
// embedded properties.
const goalsProp = getNestedObject(item, ['goals']);
if (!Array.isArray(goalsProp)) { return; }
goalsProp.forEach(goal => {
if (!goal.title) { return; }
goalsByMonth.push(goal.title);
});
});
// https://stackoverflow.com/questions/1960473/get-all-unique-values-in-a-javascript-array-remove-duplicates
const uniqueGoals = [...new Set(goalsByMonth)];
goalsByMonthYearObj[key] = uniqueGoals;
}
console.log(goalsByMonthYearObj);