1

Apologies for any repeats here, please point me in the direction of a solution if one exists.

Any other time, I seem able to display array data in ejs no problem, but this new flatten function has me stumped.

I have a nested array:

var array = 
[{
  page: {
    results: [{
        id: "1234",
        type: "page",
        title: "Deprecated Spec",
        children: {
          page: {
            results: [{
                id: "5678",
                type: "page",
                title: "Deprecated | Cash Spec"
              },
              {
                id: "9101",
                type: "page",
                title: "Deprecated | Ledger Spec",
              }
            ],
          },
        },
      },
      {
        id: "1121",
        type: "page",
        title: "Work Spec"
      }
    ]
  }
}];

And I have a flatten function:

function flatten(arr) {
  let flattened = [];
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      flattened = flattened.concat(flatten(arr[i]));
    } else {
      flattened.push(arr[i]);
    }
  }
  return flattened;
}

I set a const and console.log:

const newArr = (flatten(array))

console.log(newArr);

In the terminal I receive: [ { page: { results: [Array] } } ]

For what it's worth, I've also tried flattening this nested array with these methods, and both return the same results.

const newArr2 = Array.prototype.concat.apply([], array);

const newArr3 = array.flat();

Hmm ok, I figure I can forEach and display the data on the .ejs page, which is set as:

<% newArr.forEach(function (newArr){ %> 
        <%= newArr.title %>
    <% }) %> 

But this shows nothing.

I have the res.render functioning properly as I am able to send and display other arrays/data sets.

If I try to "get into the array" with something like this: newArr[0].page.results, or any other variances, they don't work.

What am I missing to see my flattened array (using the recursive function) in both the console.log and on my ejs page?

UPDATED: Per comments below, here is my desired output for the arrays and objects seen in var array:

[{
  page: {
    results: [
       {
        id: "1234",
        type: "page",
        title: "Deprecated Spec"
       },
       {
        id: "5678",
        type: "page",
        title: "Deprecated | Cash Spec"
       },
       {
        id: "9101",
        type: "page",
        title: "Deprecated | Ledger Spec"
        },
        {
        id: "1121",
        type: "page",
        title: "Work Spec"
        }
    ]
  }
}];

Here is a pic of my current console.log can see array/objects and console log

Many Thanks!

6
  • What are you trying to achieve with flatten? You array is not an array of arrays. So your flatten does basically nothing. Commented Sep 9, 2022 at 6:55
  • Thanks @some-user My understanding (which is new-to-node) is that I have an array inside of an array since title: Deprecated Spec has two children (title: "Deprecated | Cash Spec" & title: "Deprecated | Ledger Spec") that appear to be inside an array. Is this not correct? Commented Sep 9, 2022 at 18:01
  • 1
    flatten will only affect arrays that contain arrays as their element. Your data structure is more complicated. The elements of your array are objects which then contain arrays... Commented Sep 9, 2022 at 18:12
  • Ah thank you, I've updated my Topic title but will leave everything else for context. So how do I go about bringing the children titles/properties up to the same level as the parents? I'm not sure what to call this method if it's not 'flatten'. Is there documentation you can point toward or help with my code? Commented Sep 9, 2022 at 18:19
  • 1
    You need to adapt the implementation of flatten. Currently it does nothing. But apparently you want it to do something. If you can give the desired output of the function, people might be able to suggest how the implementation could look like. Commented Sep 9, 2022 at 18:49

1 Answer 1

1

You should adapt your code to flatten the array like this to achieve the desired output:

const array = [
  {
    page: {
      results: [
        {
          id: '1234',
          type: 'page',
          title: 'Deprecated Spec',
          children: {
            page: {
              results: [
                {
                  id: '5678',
                  type: 'page',
                  title: 'Deprecated | Cash Spec',
                },
                {
                  id: '9101',
                  type: 'page',
                  title: 'Deprecated | Ledger Spec',
                },
              ],
            },
          },
        },
        {
          id: '1121',
          type: 'page',
          title: 'Work Spec',
        },
      ],
    },
  },
]

function flatten(arr) {
  const flattened = []
  for (const { children, ...element } of arr) {
    flattened.push(element)
    if (children) {
      flattened.push(...flatten(children.page.results))
    }
  }
  return flattened
}

const flat = [{ page: { results: flatten(array[0].page.results) } }]

console.log(flat)
console.log(flat[0].page.results)


// [
//   {
//     "page": {
//       "results": [
//         {
//           "id": "1234",
//           "type": "page",
//           "title": "Deprecated Spec"
//         },
//         {
//           "id": "5678",
//           "type": "page",
//           "title": "Deprecated | Cash Spec"
//         },
//         {
//           "id": "9101",
//           "type": "page",
//           "title": "Deprecated | Ledger Spec"
//         },
//         {
//           "id": "1121",
//           "type": "page",
//           "title": "Work Spec"
//         }
//       ]
//     }
//   }
// ]

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks so much @some-user, thank you for your patience with me, I've copied your code verbatim, however, instead of the full console.log of flat that you show, all I see in console.log is [ { page: { results: [Array] } } ]
That's just the way the output is limited. Try console.log(flat[0].page.results). Your welcome, you can select the answer as the right answer if it works for you.
That works, I apologize for the follow up, this seems to be a moving target as I learn, a couple questions if you don't mind: 1) can you give a 'name' to what you're doing here? Are you flattening an array or object with arrays of objects? 2) can you please point to any documentation?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.