Q:

How to remove or add an item to a jagged array in javascript using ES6?

Say I have the following jagged array
var data = [
            ['a','b','c'],
            ['d','e',['f','g']],
            ['h','i','j']
          ];

and I want to be able to remove 'f' so that result is going to look like
var data1 = [
            ['a','b','c'],
            ['d','e',['g']],
            ['h','i','j']
          ];

Similarly I want to add 'f' after 'h' in the array above to give me
var data2 = [
            ['a','b','c'],
            ['d','e',['g']],
            ['h','f','i','j']
          ];

how can I achieve this in javascript or ES6? please note my jagged arrays can be multiple level deep the above just serves as an example.
so I need functions like
data.remove('f') to result in data1
data1.addafter('h','f') to result in data2
I tried a recursive function like below but unable to crack it...
function arrmap([head, ...tail], fn) {   
    return tail.length === 0 ? [fn(head)] : [fn(head), ...map(tail, fn)];  
}

A:

You need a recursive combination of map and filter. In this case, I would just go with a recursive function with a for...of loop:

const fn = arr => {
  const r = []
  
  for(const item of arr) {
    if(Array.isArray(item)) r.push(fn(item))    
    else if(item === 'h') r.push('h', 'f')
    else if(item !== 'f') r.push(item)  
  }
  
  return r;
}

const data = [['a','b','c'],['d','e',['f','g']],['h','i','j']]
          
const result = fn(data)

console.log(result)

If you need a more generic approach, you can extract fn:

const nestedMap = (arr, fn) => 
  arr.reduce((r, item) => {    
    const val = Array.isArray(item) ? [nestedMap(item, fn)] : fn(item)
    
    return val !== undefined ? r.concat(val) : r
  }, [])

const data = [['a','b','c'],['d','e',['f','g']],['h','i','j']]
          
const result = nestedMap(data, item => {
  if (item === 'h') return ['h', 'f']
  if (item !== 'f') return item
})

console.log(result)

