从深度嵌套数组对象结构中提取值的Javascript

xjreopfe  于 2023-02-21  发布在  Java
关注(0)|答案(1)|浏览(168)

我尝试从后端数据中提取特定字段以准备表体。传入的数据具有以下结构:

[
{
_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

但是现在我陷入了困境,因为我想隔离goals数组的字段,它在对象中,在每个月的数组中,而每个月的数组包含在一个对象中。我试过使用Object. keys and maps,然后从这里开始:https://dev.to/flexdinesh/accessing-nested-objects-in-javascript--9m4遇到了一个用于获取深度嵌套项的函数。但我仍然把它搞得一团糟,我的头在旋转,试图弄清楚它的意义。我查看了lodash的map和属性,但不确定如何实现给定的嵌套层,我试图在groupBy对象内的动态命名数组上工作。这就是我所处的位置,但我得到了错误www.example.comi.mapis 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知识是可怕的,这并没有帮助...

dwbf0jvd

dwbf0jvd1#

你得到的错误消息i.map不是一个函数,意味着变量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: "Cook" },
                { title: "Spend" },
                { title: "Clean" }
            ]
        },
        {
            user: "62410a1dcaac9a3d0528de7a", location: "place", visitStart: "2022-08-11T21:00:57.000Z",
            goals: [
                { title: "Cook" },
                { title: "Clean" }
            ]
        }
    ],
    8: [
        {
            user: "62410a1dcaac9a3d0528de7a", location: "Home", visitStart: "2022-09-12T22:00:00.000Z",
            goals: [
                { title: "Cook" },
                { title: "Budget" },
                { title: "Clean" }
            ]
        },
        { 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 objects listed for each month.
  let goalsByMonth = [];
  users.map(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()' and then
    // concatenate goals array to the existing 
    // goals-by-month array.
    goalsByMonth = goalsByMonth.concat(goalsProp.map(goal => goal.title));
  });
  // 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);

相关问题