For example, if I have these arrays:
var name = [\"Bob\",\"Tom\",\"Larry\"];
var age = [\"10\", \"20\", \"30\"];
And I use name.sort
I was looking for something more generic and functional than the current answers.
Here's what I came up with: an es6 implementation (with no mutations!) that lets you sort as many arrays as you want given a "source" array
/**
* Given multiple arrays of the same length, sort one (the "source" array), and
* sort all other arrays to reorder the same way the source array does.
*
* Usage:
*
* sortMultipleArrays( objectWithArrays, sortFunctionToApplyToSource )
*
* sortMultipleArrays(
* {
* source: [...],
* other1: [...],
* other2: [...]
* },
* (a, b) => { return a - b })
* )
*
* Returns:
* {
* source: [..sorted source array]
* other1: [...other1 sorted in same order as source],
* other2: [...other2 sorted in same order as source]
* }
*/
export function sortMultipleArrays( namedArrays, sortFn ) {
const { source } = namedArrays;
if( !source ) {
throw new Error('You must pass in an object containing a key named "source" pointing to an array');
}
const arrayNames = Object.keys( namedArrays );
// First build an array combining all arrays into one, eg
// [{ source: 'source1', other: 'other1' }, { source: 'source2', other: 'other2' } ...]
return source.map(( value, index ) =>
arrayNames.reduce((memo, name) => ({
...memo,
[ name ]: namedArrays[ name ][ index ]
}), {})
)
// Then have user defined sort function sort the single array, but only
// pass in the source value
.sort(( a, b ) => sortFn( a.source, b.source ))
// Then turn the source array back into an object with the values being the
// sorted arrays, eg
// { source: [ 'source1', 'source2' ], other: [ 'other1', 'other2' ] ... }
.reduce(( memo, group ) =>
arrayNames.reduce((ongoingMemo, arrayName) => ({
...ongoingMemo,
[ arrayName ]: [
...( ongoingMemo[ arrayName ] || [] ),
group[ arrayName ]
]
}), memo), {});
}