Как отсортировать объекты одного массива по порядку объектов другого массива?

Обновлено требование от 06.04.2021:

У меня есть два массива объектов: arrX и arrY. Необходимо отсортировать объекты «arrY» так же, как и «arrX». Какой путь самый короткий или лучший?

Примечание: объекты, которые имеют тип, отличный от типов arrX, должны попасть в конец, т.е. "type: 'X'" здесь.

const arrX = [
     {type: 'C', category: 'CAT2'},
     {type: 'A', category: 'CAT1},
     {type: 'B', category: 'CAT3'},
    ]    

const arrY = [
             {type: 'B', category: 'CAT3'},
             {type: 'A', category: 'CAT1'},
             {type: 'C', category: 'CAT2'},
             {type: 'B', category: 'CAT3'},
             {type: 'A', category: 'CAT1'},
             {type: 'X', category: 'CAT4'},
             {type: 'B', category: 'CAT2'},
             {type: 'X', category: 'CAT4'},
             {type: 'X', category: 'CAT5'},
             {type: 'A', category: 'CAT1'},
             {type: 'C', category: 'CAT2'}, 
    ]

Должно быть отсортировано как:

const arrX = [
     {type: 'C', category: 'CAT2'},
     {type: 'C', category: 'CAT2'},
     {type: 'A', category: 'CAT1'},
     {type: 'A', category: 'CAT1'},
     {type: 'A', category: 'CAT1'},
     {type: 'B', category: 'CAT3'},
     {type: 'B', category: 'CAT3'},
     {type: 'X', category: 'CAT4'},
     {type: 'B', category: 'CAT2'},
     {type: 'X', category: 'CAT4'},
     {type: 'X', category: 'CAT5'}, 
    ]
# ecmascript-6 sorting logic
Источник
Codelisting
за 1 против

Вы можете взять объект для заказа со значением по умолчанию для неизвестных типов.

const
    arrX = [{ type: 'C' }, { type: 'A' },  { type: 'B' }],
    arrY = [{ type: 'B' }, { type: 'A' }, { type: 'C'  }, { type: 'B' }, { type: 'A' }, { type: 'X' }, { type: 'B' }, { type: 'X' }, { type: 'X' }, { type: 'A'  }, { type: 'C' }],
    order = Object.fromEntries(arrX.map(({ type }, i) => [type, i + 1]));
    
order.default = Number.MAX_VALUE;

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

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

  • 0
    ваш до сих пор хороший, но он может не сработать, если нам нужно сравнить 2 свойства из объектов 'arrX', например [{type: 'A', category: 'xyz'}, {type: 'A' , category: 'mnp'}];
  • 0
    как бы вы сравнили другую недвижимость?
за 0 против

Я бы добавил то, что было бы сопоставимо вarrX . Далее я добавилindex кarrY чтобы быть более различимым.

const addIndex = (list) => list.map((item, index) => ({ ...item, index }));
const targetIndex = (targets, element) => {
  const found = targets.find((item) => item.type === element.type);
  return found ? found.index : null;
};

const sortByType = (target, source) => {
  const targetWithId = addIndex(target);
  const sourceWithId = addIndex(source);

  sourceWithId.sort((a, b) => {
    const indexA = targetIndex(targetWithId, a);
    const indexB = targetIndex(targetWithId, b);
    if (indexA === indexB) {
      return 0;
    }

    if (indexA === null) {
      return 1;
    }

    if (indexB === null) {
      return -1;
    }

    return indexA - indexB;
  });

  return sourceWithId;
};

result = sortByType(arrX, arrY);

что даст:

[
  { type: 'C', index: 2 },
  { type: 'C', index: 10 },
  { type: 'A', index: 1 },
  { type: 'A', index: 4 },
  { type: 'A', index: 9 },
  { type: 'B', index: 0 },
  { type: 'B', index: 3 },
  { type: 'B', index: 6 },
  { type: 'X', index: 5 },
  { type: 'X', index: 7 },
  { type: 'X', index: 8 }
]
  • 0
    спасибо за ваше решение, но оно кажется слишком сложным.
  • 0
    @Paveloosha Я явно расширил логику, чтобы вы могли лучше понять. Сложность, кажется, заключается в том, что я и добавляю index ключ к обоим массивам, чтобы вы поняли, как работает сортировка. Это предложение позволяет вам расширяться, если у вас есть несколько свойств для сравнения, как вы предложили в комментарии к другому ответу.
Codelisting
Популярные категории
На заметку программисту