Steamroller seems to produce valid output but does not pass tests

Tell us what’s happening:
I’m getting the right outputs so far as I can tell, but not passing any of the tests.

  1. Is my solution valid (I think the console.log() statement suggests it is)?
  2. If so, why doesn’t it pass the tests?

Any help appreciated.

Your code so far


function steamrollArray(arr) {
  // I'm a steamroller, baby
  let getVal = (item) => {
    if (Array.isArray(item)) {
      return item.map(el=>getVal(el))
    } else {
      return item
    }
  }

  let flat = arr.reduce((acc,item) => {
    return [...acc, getVal(item)]
    },[])

  //log just for debugging
  console.log(flat.reduce((acc,item) => {
    if (item != '') {
      return [...acc,item]
    } else {
      return acc
    }
  },[]))

  return flat.reduce((acc,item) => {
    if (item != '') {
      return [...acc,item]
    } else {
      return acc
    }
  },[])
}

steamrollArray([[["a"]], [["b"]]]);
steamrollArray([1, [2], [3, [[4]]]]);
steamrollArray([1, [], [3, [[4]]]]);
steamrollArray([1, {}, [3, [[4]]]]);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/steamroller

Maybe I’m misunderstanding, for the first test it is supposed to return

["a", "b"]

but it seems that you are returning:

[[["a"]], [["b"]]]

Which to me seems unchanged.

1 Like

Ah, I didn’t realise that console.log() would automatically flatten the output. So when it says ‘a,b’ in console, this can also be [[[“a”]],[[“b”]]].

Back to the drawing board then, I guess.

I don’t think console.log would flatten the results.

1 Like

Perhaps not, in devtools? The console on the freecodecamp page seems to though. See attached snip (this is why I thought the code was working).

Use console.log(JSON.stringify( ... ))

It will show you there what is your output

1 Like

Also, for testing purposes, can I suggest to store the resul of your method in a variable and then both console.log it and return it? In this way you don’t have to pieces of code to update. Later you can remove the extra variable declaration and return that value directly and chain the various methods, once you get the desired output.

1 Like

Yes, thanks for the input. I’ve solved this challenge now, but you are correct it’s a bit messy to repeat the lines inside the console.log() and the return statement. I could’ve tidied that up a bit before posting here sorry.

After Kevin’s first response above, I re-read my own code and understood what was going on. The solution I ended up with was much neater. I’d paste it in here but I’m not sure how to mark as a spoiler (if that’s possible).

It leads me to ask one question relating to array spread syntax though. Often instead of .concat() I will use something like [ …arr, newItem] but it seems this can’t be done when newItem is a function call? Something like […arr, steamrollArray(item)]. Is that correct?

It depends on how steamrollArray() is made - if you use recursion you need your function to have a condition for which recursion doesn’t happen, or the function will call itself infinitely

To post a spoiler you can hide it using [spoiler][/spoiler] tags

1 Like

Ah, yes ok. What I mean to ask is related to including a function call inside an array definition.

In other words this worked:

function steamrollArray(arr) {
  return arr.reduce((acc,item)=>Array.isArray(item)? acc.concat(steamrollArray(item)) : [...acc,item],[])
}

But this did not:

function steamrollArray(arr) {
  return arr.reduce((acc,item)=>Array.isArray(item)? [...acc, steamrollArray(item)] : [...acc,item],[])
}

I don’t think it matters, since the first syntax works. I just wondered if the second syntax should be possible.