2

I'm trying to rearrange sorting of an array. Let's say I have the following structure

    const array = [{
     location: 'Table 2',
     data: {..}
    }, {
     location: 'Unassigned',
     data: {..}
    }, {
     location: 'Table 1',
     data: {..}
}
];

What's the proper way of moving 'Table 1' to index 0, 'Table 2' right after it (keep same order for Table 3, 4, etc), and 'Unassigned' always to the end. Preferably with lodash.

Here's what I tried so far

  forEach(allItemsSorted, (item, index) => {
    const total = allItemsSorted.length;
    let hasUnassigned = false;
    if (item.location === 'Unassigned') {
      allItemsSorted[total] = item;
      hasUnassigned = true;
    }
    if (hasUnassigned && index === total) {
      return;
    }
    allItemsSorted[index] = item;
  })
brk
  • 48,835
  • 10
  • 56
  • 78
Alex
  • 1,210
  • 3
  • 21
  • 34

5 Answers5

1

You could take an object for the wanted order and a default value for unknown values for moving this items to the end of the array.

const
    array = [{ location: 'Table 2', data: {} }, { location: 'Unassigned', data: {} }, { location: 'Table 1', data: {} }],
    order = { 'Table 1': 1, 'Table 2': 2, default: Infinity };

array.sort(({ location: a }, { location: b }) =>
    (order[a] || order.default) - (order[b] || order.default));

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

For sorting only 'Unassigned' to the end and all other values by ascending order, you could use the above mentioned order object as well, but with changed values for known and unown strings.

const
    array = [{ location: 'Table 2', data: {} }, { location: 'Unassigned', data: {} }, { location: 'Table 1', data: {} }],
    order = { Unassigned: 1 };

array.sort(({ location: a }, { location: b }) =>
    (order[a] || 0) - (order[b] || 0) || a.localeCompare(b));

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

You can use Array.sort() - always move the Unassigned to the end (the two ifs). Sort the other items using String.localeCompare() with the numeric option.

Note: I use array spread - [...array] - to clone the array, so the original won't be mutated. You can skip that, if you want to change the original array.

const array = [{location:'Table 27'}, {location:'Table 2'}, {location: 'Unassigned'}, {location: 'Table 11'}];

const result = [...array].sort(({ location: a }, { location: b }) => {
  if(a === 'Unassigned') return 1;
  if(b === 'Unassigned') return -1;
  
  return a.localeCompare(b, undefined, {numeric: true});
});

console.log(result);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
1

What about doing sorting on the array if you have location values starting with Table and unassigned has Unassigned as value. Will work for that scenario. But be careful for other values unless they are what you intend the result to be.

const array = [{location:'Table 2', data: {}}, {location: 'Unassigned', data: {}}, {location: 'Table 1', data: {}}];
array.sort(function(a,b){
  return a.location.localeCompare(b.location);
});
console.log(array);
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62
1

If you wish to rearrange an array, always look for Array.sort method. Creating a new array with custom addition will only cause difficulties.

You can try something like this:

  • Create a function that accepts location and returns a numeric value.
  • Use this value to sort in any order you wish.

const array = [
  {location:'Table 2', data: {}},
  {location: 'Unassigned', data: {}},
  {location: 'Table 1', data: {}},
  {location: 'Table 11', data: {}},
  {location: 'Table 31', data: {}},
  {location: 'Table 3', data: {}},
];

array.sort(function(a,b) {
  return getSortValue(a.location) - getSortValue(b.location);
});

function getSortValue(location) {
  return location === 'Unassigned' ? Number.MAX_SAFE_INTEGER : location.match(/\d+/)[0];
}

console.log(array)
Rajesh
  • 24,354
  • 5
  • 48
  • 79
  • **Note:** If you feel there is something wrong about this answer or its missing something, please share your views in comment along with your vote. Thanks! – Rajesh Oct 29 '18 at 09:15
0

How about this

var data1 = [{location:'Table 2', data: {}}, {location: 'Unassigned', data: {}}, {location: 'Table 1', data: {}}, {location: 'Table 12', data: {}}, {location: 'Table 22', data: {}}, {location: 'Unassigned', data: {}}];

data.sort((a,b)=> a.location > b.location).filter(item => item.location != 'Unassigned').push([...data.filter(item => item.location == 'Unassigned')]);

Result

[{
"location": "Table 1",
"data": {}
},
{
"location": "Table 12",
"data": {}
},
{
"location": "Table 2",
"data": {}
},
{
"location": "Table 22",
"data": {}
},
{
"location": "Unassigned",
"data": {}
},
{
"location": "Unassigned",
"data": {}
}]
yureka
  • 31
  • 8