-1

Updated requirement on 04/06/2021:

I have two array of objects, arrX and arrY. Need to sort the objects of 'arrY' same as the order of 'arrX'. What is the shortest or best way?

Note: Objects which has type other than types of arrX should got to the bottom ie. "type: 'X'" here.

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'}, 
    ]

Should Be sorted as:

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'}, 
    ]
Paveloosha
  • 563
  • 2
  • 6
  • 15
  • 1
    Did you try using `arrY.sort`? – evolutionxbox Jun 03 '21 at 14:44
  • 5
    [Duplicate](//google.com/search?q=site%3Astackoverflow.com+js+sort+objects+by+property) of [Sort array of objects by string property value](/q/1129216/4642212) and [duplicate](//google.com/search?q=site%3Astackoverflow.com+js+sort+array+according+to+another+array) of [Javascript - sort array based on another array](/q/13304543/4642212) (use the top-voted answer (the one with the simple `indexOf` comparison), not the accepted one). It’s easier if you had `const arrX = [ "C", "A", "B" ]` insead. – Sebastian Simon Jun 03 '21 at 14:45
  • @SebastianSimon, I don't think it's duplicate. – Paveloosha Jun 03 '21 at 17:41

2 Answers2

1

You could take an object for the order with a default value for unknown types.

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; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • your one is the good one till now, but it may not work if we need to compare 2 properties from objects of the 'arrX' like [{type: 'A', category: 'xyz'}, {type: 'A', category: 'mnp'}]; – Paveloosha Jun 03 '21 at 17:39
  • how would you like to compare the other property? – Nina Scholz Jun 03 '21 at 18:06
0

I would add something that would be comparable in arrX. In the following, I have added an index to arrY to be more distinguishable.

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);

which would yield:

[
  { 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 }
]
Danosaure
  • 3,578
  • 4
  • 26
  • 41
  • thanks for your solution but it seems too complex. – Paveloosha Jun 03 '21 at 17:40
  • @Paveloosha I have explicitly expanded the logic for you to understand better. The complexity seems to be just that I and adding the `index` key to both array for you to understand how the sorting works. This proposition allows you to expand if you have multiple properties to compare with, as you suggested in the comment of the other answer. – Danosaure Jun 04 '21 at 00:35