What is the equation to determine an element's index in a jagged array given it's index from the equivalent flattened array?

302 Views Asked by At

If one has a jagged array of N dimensions and an index of an element in the flattened representation of that array, is there an equation that would retrieve the index of that element in the original, jagged array?

Example:

Assume the jagged_array is:

[[0, 1, 2, 3].
 [4, 5],
 [6]
 [7, 8, 9, 10, 11]]

The element 7 has an index of jagged_array_flattened[7]. If I have it's position in the flattened array, how can I get it's position in the original array (it would be jagged_array[3][0].

Would be cool if it did not matter how many dimensions you had, but I am mostly dealing with 2D arrays. If there is no equation, perhaps some pseudocode?

Thanks.

Edit: I feel like the N-dimensions makes it too difficult to generalize, so unless I am wrong, perhaps the focus should be on 2D arrays.

Edit 2: Here is a quick write up of my solution in code.

function getValue(list, flattenedIndex) {
    let firstIndexOfSubList = 0;
    let lastIndexOfSubList = 0;
    for (let i = 0; i < list.length; i++) {
        lastIndexOfSubList += list[i].length - 1;
        if (lastIndexOfSubList === flattenedIndex) return list[i][lastIndexOfSubList - firstIndexOfSubList];
        else if (Math.max(flattenedIndex, lastIndexOfSubList) === flattenedIndex) {
            lastIndexOfSubList++;
            firstIndexOfSubList = lastIndexOfSubList;
        } else return list[i][flattenedIndex - firstIndexOfSubList];
    }
}

Edit 2: A solution with binary search if you have a precomputed list of lengths:

function binaryWhatever(jsonb, flattenedIndex) {
    let lo = 0;
    let hi = jsonb.length

    while (lo < hi) {
        let mid = Math.floor((lo + hi) / 2);
        if (flattenedIndex < jsonb[mid]) hi = mid;
        else lo = mid + 1;
    }
    let index1 = lo - 1;
    let index2 = flattenedIndex - jsonb[lo - 1];

    return [index1, index2]
}
```
1

There are 1 best solutions below

7
On BEST ANSWER

Your attempt can be improved slightly by combining the first and third cases together:

if (lastIndexOfSubList >= flattenedIndex) return list[i][lastIndexOfSubList - firstIndexOfSubList];

Note that if you only want to perform this conversion operation once, then you cannot do better than such a linear for-loop because you at least have to read the lengths of all the sublists up to the point where the answer is.

However, if you want to perform this conversion multiple times, then there is in fact a much more efficient way. To understand it, you will have to learn and understand binary search. The gist of the efficient solution is that you precompute the total length of the first $k$ sublists, for each $k$ from $1$ to list.length. Then you binary search that precomputed array (of cumulative lengths) to find the sublist in which the answer lies. And then you can extract the answer easily from there.

Have a try first and let me know in the comments if you need further help!