[SOLVED] How to convert the index of a flatten multidimensional array (any depth) to the original index?

Issue

This Content is from Stack Overflow. Question asked by displaydisplayname

For example, suppose I have a multidimensional array:

const a1=[["a",["a","b"]],"b",[["b"],"c"]];

which the flatten from is

const a2=["a","a","b","b","c","c"];

and accessing a2[2] is equivalent to a1[0][1][1], also access a2[3] is equivalent to a1[1].

However I’m not interested in what the element is in such index, instead I want a function that can convert the index of a2 equivalent to in a1, eg:

magicFunction(2,[["a",["a","b"]],"b",[["b"],"c"]])

returns [0,1,1],

also

magicFunction(3,[["a",["a","b"]],"b",[["b"],"c"]])

returns [1]. And the input multidimensional array can be any depth (more than 3 layers). How do I write such magic function?

Note: I know that may be easy to do if I know the array is 2d and the sub-array have same number of elements:

const a1=[["a","a"],["b","b"],["c","c"]];
const magicFunction=function(target,a){
  let count=0;
  for(let i=0;i<a.length;i++){
    for(let j=0;j<a[i].length;j++){
        if(count==target){
            return [i,j];
        }
        count++;
    }
  }
  return [];
};
alert(magicFunction(3,a1));

However now I need the function to accept a with n-dimensional array which d is unknown before testing, which I don’t know how many layers of for-loop should I write to handle it, also the length of each sub-array may not be the same.



Solution

Here’s a recursive function that generates the path by traversing the array and counting values until it reaches the n’th value. The function returns either an array of the path (if we reach the n’th value) or the current count (if we don’t).

const magicFunction = (index, array, count=0) => {
  for (let idx = 0; idx < array.length; idx++) {
    if (Array.isArray(array[idx])) {
      let res = magicFunction(index, array[idx], count)
      if (Array.isArray(res)) return [idx].concat(res)
      else count = res
    }
    else {
      if (count == index) return [idx]
      count++
    }
  }
  return count
}

for (i = 0; i < 6; i++) {
  res = magicFunction(i, [["a",["b","c"]],"d",[["e"],"f"]])
  console.log(`${i} : [${res}]`)
}


This Question was asked in StackOverflow by displaydisplayname and Answered by Nick It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?