In your example, because is an array of string
we can use a ranking object to reorder the string array:
let rank = { 'a': 0, 'b': 1, 'c': 2, 'd': 0.5, 'e': 4 };
arr.sort( (i, j) => rank[i] - rank[j] );
We can use this approach to write a move
function that works on a string array:
function stringArrayMove(arr, from, to)
{
let rank = arr.reduce( (p, c, i) => ( p[c] = i, p ), ({ }) );
// rank = { 'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4 }
rank[arr[from]] = to - 0.5;
// rank = { 'a': 0, 'b': 1, 'c': 2, 'd': 1.5, 'e': 4 }
arr.sort( (i, j) => rank[i] - rank[j] );
// arr = [ 'a', 'd', 'b', 'c', 'e' ];
}
let arr = [ 'a', 'b', 'c', 'd', 'e' ];
stringArrayMove(arr, 3, 1);
console.log( JSON.stringify(arr) );
_x000D_
If, however, the thing we wanted to sort is an array of object, we can introduce the ranking as a new property of each object, i.e.
let arr = [ { value: 'a', rank: 0 },
{ value: 'b', rank: 1 },
{ value: 'c', rank: 2 },
{ value: 'd', rank: 0.5 },
{ value: 'e', rank: 4 } ];
arr.sort( (i, j) => i['rank'] - j['rank'] );
We can use Symbol
to hide the visibility of this property, i.e. it will not be shown in JSON.stringify
. We can generalize this in an objectArrayMove
function:
function objectArrayMove(arr, from, to) {
let rank = Symbol("rank");
arr.forEach( (item, i) => item[rank] = i );
arr[from][rank] = to - 0.5;
arr.sort( (i, j) => i[rank] - j[rank]);
}
let arr = [ { value: 'a' }, { value: 'b' }, { value: 'c' }, { value: 'd' }, { value: 'e' } ];
console.log( 'array before move: ', JSON.stringify( arr ) );
// array before move: [{"value":"a"},{"value":"b"},{"value":"c"},{"value":"d"},{"value":"e"}]
objectArrayMove(arr, 3, 1);
console.log( 'array after move: ', JSON.stringify( arr ) );
// array after move: [{"value":"a"},{"value":"d"},{"value":"b"},{"value":"c"},{"value":"e"}]
_x000D_