1

I need to re-order multidimensional arrays of with n, where n can be up to 50 or more

from here I can reorder if I list All the column indices, which again could be up to 50 or more

function rearrange(rows, pos) {
  return rows.map(function(cols) {
    return pos.map(function(i) {
      return cols[i];
    });
  });
}

I want to only list the indices of the columns I want to reorder and move these columns to the beginning of the array leaving all the other columns in the order they are left in

Bob|Carol|Ted|Alice
a  |b    |c  |d
1  |2    |3  |4
A  |B    |C  |D 

If the list of indices is list=[3] so I get

Alice|Bob|Carol|Ted
d    |a  |b    |c
4    |1  |2    |3
D    |A  |B    |C

list = [2,3]

Ted|Alice|Bob|Carol
c  |d    |a  |b
3  |4    |1  |2
C  |D    |A  |B

Thank you

xyz
  • 2,253
  • 10
  • 46
  • 68

1 Answers1

2

This may not be the most efficient route, but should work for what you are trying to accomplish.

  1. Make a copy of the original headers
  2. Create new headers array in desired arrangement based on "toFront" array
  3. Map through all the rows:
    • converting each row to an object using the original headers
    • map over the new headers and return the associated value from the row object

const data = [
  [ 'Bob', 'Carol', 'Ted', 'Alice' ],
  [ 'a', 'b', 'c', 'd' ],
  [ 1, 2, 3, 4 ],
  [ 'A', 'B', 'C', 'D']
];

const rearrange = (rows=[], toFront=[]) => {

  const originalHeaders = [...rows[0]]

  const remainingHeaders = [...rows[0]]

  const frontHeaders = toFront.map(index => {
    // set this one to null, to be filtered out later
    remainingHeaders[index] = null
    // grab the original header value
    return originalHeaders[index]
  })
  // you don't want to modify the original headers directly,
  // seeing as you might not end up with the desired result
  // if you pass a `toFront` value like [1,2] or where
  // any of the values come after another
  
  const newHeaders = [
    ...frontHeaders,
    ...remainingHeaders.filter(v => v !== null)
  ]
  
  return data.map(r => {
    let row = {}
    r.forEach((value, i) => {
      row[originalHeaders[i]] = value
    })

    return newHeaders.map(h => row[h])
  })
}

console.log(rearrange(data, [2,1]))
andersryanc
  • 939
  • 7
  • 19
  • I can follow about 70% of this so thank you for the comments! I will spend some time studying what you wrote. Seems clever to me. Thanks – xyz Nov 20 '20 at 14:17