0

assuming an N-th dimensional array, eg.

const array = [
  "1",
  ["2","2"],
  [["3","3"],["3","3"]],
  [
    [
      [["4","4"],"3"],
      [["4","4"],"3"]
    ],
  ],
  [["3","3"],["3","3"]],
  ["2","2"],
  "1"
];

I can only find methods to flatten arrays from shallow-end of the index up, but I need to flatten/reduce or otherwise handle only the deepest (or any arbitrary) index level.

When running the deepest level I am looking for an array output something along the lines of

array = [
  "1",
  ["2","2"],
  [["3","3"],["3","3"]],
  [
    [
      ["4,4","3"],
      ["4,4","3"]
    ],
  ],
  [["3","3"],["3","3"]],
  ["2","2"],
  "1"
];

I cannot find a solution that isn't garbage... (over-complicated/incredibly messy) Any help would be appreciated

Scribble
  • 11
  • 4
  • 4
    Asking us to just find a solution isn't enough; you need to provide us _your own attempt_ at solving the problem and then we can help. – chazsolo Jul 16 '20 at 16:14
  • 1
    And you should also post your expected results as well. – Panwen Wang Jul 16 '20 at 16:20
  • As the problem is interesting, it's a shame you haven't included any attempt to solve it. Start [here](https://stackoverflow.com/questions/11922383/how-can-i-access-and-process-nested-objects-arrays-or-json), then if you get stuck, ask a question. – Teemu Jul 16 '20 at 16:22
  • "garbage" is pretty subjective here. What is garbage about what you've found? Too long? Not performant enough? Perhaps post links to SO questions that you have already visited that did not help you. – chazsolo Jul 16 '20 at 16:24
  • Thank you for the quick responses, apologies that i didn't include any working, I have been working on this for days now. I will definitely add a framework next time as well as an expected outcome. First post jitters... – Scribble Jul 16 '20 at 16:49

2 Answers2

1

You could create a function that will take the data and level that you want to flatten and will flatten only that level. Then to get the last level you can create another function.

const array = ["1",["2","2"],[["3","3"],["3","3"]],[[[["4","4"],"3"],[["4","4"],"3"]],[["",""],["",""]]],[["3","3"],["3","3"]],["2","2"],"1"];

function lastLvl(data, lvl = 0) {
  return data.reduce((r, e) => {
    if (lvl > r) r = lvl

    if (Array.isArray(e)) {
      const nlvl = lastLvl(e, lvl + 1);
      if (nlvl > r) r = nlvl
    }

    return r
  }, 0)
}

function flattenLvl(data, lvl, clvl = 1) {
  return data.reduce((r, e) => {
    if (Array.isArray(e)) {
      const nested = flattenLvl(e, lvl, clvl + 1);
      if (clvl == lvl) r.push(...nested);
      else r.push(nested)
    } else {
      r.push(e)
    }

    return r;
  }, [])
}

const lvl = lastLvl(array)
const result = flattenLvl(array, lvl)
console.log(result)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
  • Thank you for the quick response, apologies for not including my intended output. I'm looking to reduce to lowest elements and update the original array so it looks something like this after running the deepest index\r\n array = [ "1", ["2","2"], [["3","3"],["3","3"]], [ [ ["4,4","3"], ["4,4","3"] ], [["",""], ["",""]] ], [["3","3"],["3","3"]], ["2","2"], "1" ]; – Scribble Jul 16 '20 at 17:13
  • That worked thank you. I'll update with the integrated solution tomorrow. Thank you again, I appreciate your time. – Scribble Jul 19 '20 at 16:05
0

You can use a recursive function that gets the array and a desired level, and then stop recurring when the level is 1, at which point you just filter out the non-array values in that (sub)array:

function extractLevel(arr, level) {
    return level <= 1 
        ? arr.filter(val => !Array.isArray(val))
        : arr.filter(Array.isArray)
             .flatMap(arr => extractLevel(arr, level-1));
}

// demo
const array = ["1",["2","2"],[["3","3"],["3","3"]],[[[["4","4"],"3"],[["4","4"],"3"]],[["",""],["",""]]],[["3","3"],["3","3"]],["2","2"],"1"];
// extract the values (not arrays) at level 3:
console.log(extractLevel(array, 3));
trincot
  • 317,000
  • 35
  • 244
  • 286