Denis
Denis

Reputation: 296

Sortng array by order to another array

I have two arrays:

Main array:

const items = [
  "Лопата 123",
  "Empty Forest",
  "Forever young",
  "My ears",
  "Most Important",
  "16 Tons",
  "Operation Flashpoint",
  "Prize A1",
  "Нарешті літо",
];

And keys array:

const keys = ["Prize A1", "Forever young", "Most Important"];

I want to sort the first array in the order of the key array, for example:

const expected = [
  "Prize A1",
  "Forever young",
  "Most Important",
  "Лопата 123",
  "Empty Forest",
  "My ears",
  "16 Tons",
  "Operation Flashpoint",
  "Нарешті літо",
]

I writed some code, but it doesn’t work as it should:

const expectedOrder = items.sort(function(a, b) {
   return keys.indexOf(b) - keys.indexOf(a);
});

 const items = [
    "Лопата 123",
    "Empty Forest",
    "Forever young",
    "My ears",
    "Most Important",
    "16 Tons",
    "Operation Flashpoint",
    "Prize A1",
    "Нарешті літо",
  ];
    
const keys = ["Prize A1", "Forever young", "Most Important"];

const expectedOrder = items.sort(function(a, b) {
   return keys.indexOf(b) - keys.indexOf(a);
});

console.log('expectedOrder', expectedOrder)

Upvotes: 1

Views: 51

Answers (3)

C.Champagne
C.Champagne

Reputation: 5489

You should check if the items are included in your keys array.

If both are included or not included then the order is kept unchanged else the item included in keys must be placed before in the list.

 const items = [
    "Лопата 123",
    "Empty Forest",
    "Forever young",
    "My ears",
    "Most Important",
    "16 Tons",
    "Operation Flashpoint",
    "Prize A1",
    "Нарешті літо",
  ];
    
const keys = ["Prize A1", "Forever young", "Most Important"];

const expectedOrder = items.sort(function(a, b) {
   const incA = keys.includes(a);
   const incB = keys.includes(b);
   
   return (incA === incB)? 0 : ((incA)? -1 : 1);
});

console.log('expectedOrder', expectedOrder)

Upvotes: 0

Nikita Madeev
Nikita Madeev

Reputation: 4380

indexOf your keys:

  • "Prize A1" = 0
  • "Forever young" = 1
  • "Most Important" = 2

sort puts the item higher if the value is greater than 0, but in your case "Prize A1" < "Most Important"

You can reverse your keys array:

const items = [
    'Лопата 123',
    'Empty Forest',
    'Forever young',
    'My ears',
    'Most Important',
    '16 Tons',
    'Operation Flashpoint',
    'Prize A1',
    'Нарешті літо',
];

const keys = ['Prize A1', 'Forever young', 'Most Important'].reverse();

const expectedOrder = items.sort(function(a, b) {
    return keys.indexOf(b) - keys.indexOf(a);
});

console.log('expectedOrder', expectedOrder);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386604

You could sort with a default value for -1 indices.

 const
     items = ["Лопата 123", "Empty Forest", "Forever young", "My ears", "Most Important", "16 Tons", "Operation Flashpoint", "Prize A1", "Нарешті літо"],
     keys = ["Prize A1", "Forever young", "Most Important"];

items.sort((a, b) => ((keys.indexOf(a) + 1) || Number.MAX_VALUE) - ((keys.indexOf(b) + 1) || Number.MAX_VALUE));

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

An even shorter approach takes an object for sorting with a default value.

 const
     items = ["Лопата 123", "Empty Forest", "Forever young", "My ears", "Most Important", "16 Tons", "Operation Flashpoint", "Prize A1", "Нарешті літо"],
     order = { "Prize A1": 1, "Forever young": 2, "Most Important": 3, default: Number.MAX_VALUE };

items.sort((a, b) => (order[a] || order.default) - (order[b] || order.default));

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

Upvotes: 1

Related Questions