Ohhh
Ohhh

Reputation: 435

Typescript - How to sort one object array based on another array with sorted object's fields?

Typescript - How to sort one object array based on another array with sorted object's fields?

For example:

Array A not sorted

Array B with object's field sorted

Tries to sort Array A based on Array B's order.

const unsortedArray = [
{
    repId: "4",
    symbol: "MSLA",
    orderNo: "20180518-00004"
},
{
    repId: "2",
    symbol: "TSLA",
    orderNo: "20180518-00003"
},
{
    repId: "55",
    symbol: "APPL",
    orderNo: "20180518-00001"
},
{
    repId: "22",
    symbol: "FB",
    orderNo: "20180518-0002"
}]

const sortedArrayField = [
    "20180518-00001", 
    "20180518-00002", 
    "20180518-00003", 
    "20180518-00004"
]

// This is the sorted order that I want
const sortedArray = [
{
    repId: "55",
    symbol: "APPL",
    orderNo: "20180518-00001"
},
{
    repId: "22",
    symbol: "FB",
    orderNo: "20180518-00002"
},
{
    repId: "2",
    symbol: "TSLA",
    orderNo: "20180518-00003"
},
{
    repId: "4",
    symbol: "MSLA",
    orderNo: "20180518-00004"
}]

The sorted field array can be anything, not just order number, could be symbol, status, etc... Any suggestion???

Looked up some example and tried a few approach, but no elegant solution so far with typescript. No external library plz.

Upvotes: 1

Views: 1270

Answers (4)

Josu Goñi
Josu Goñi

Reputation: 1274

You can do it like this: sortedArrayField.map(orderNo => unsortedArray.find(item => item.orderNo === orderNo))

You can also use this if you have more than one object in the same position:

var sortedArray2 = [];
sortedArrayField.forEach(orderNo => {
  sortedArray2 = sortedArray2.concat(unsortedArray.filter(item => item.orderNo === orderNo));
});

const unsortedArray = [
{
    repId: "4",
    symbol: "MSLA",
    orderNo: "20180518-00004"
},
{
    repId: "2",
    symbol: "TSLA",
    orderNo: "20180518-00003"
},
{
    repId: "55",
    symbol: "APPL",
    orderNo: "20180518-00001"
},
{
    repId: "22",
    symbol: "FB",
    orderNo: "20180518-00002"
},
{
    repId: "22 (2)",
    symbol: "FB",
    orderNo: "20180518-00002"
}]

const sortedArrayField = [
    "20180518-00001", 
    "20180518-00002", 
    "20180518-00003", 
    "20180518-00004"
];

var sortedArray = sortedArrayField.map(orderNo => unsortedArray.find(item => item.orderNo === orderNo));

console.log(sortedArray);

var sortedArray2 = [];
sortedArrayField.forEach(orderNo => {
  sortedArray2 = sortedArray2.concat(unsortedArray.filter(item => item.orderNo === orderNo));
});

console.log(sortedArray2);

Upvotes: 0

amrender singh
amrender singh

Reputation: 8239

Try the following :

const unsortedArray = [
{
    repId: "4",
    symbol: "MSLA",
    orderNo: "20180518-00004"
},
{
    repId: "2",
    symbol: "TSLA",
    orderNo: "20180518-00003"
},
{
    repId: "55",
    symbol: "APPL",
    orderNo: "20180518-00001"
},
{
    repId: "22",
    symbol: "FB",
    orderNo: "20180518-00002"
}];

const sortedArrayField = [
    "20180518-00001", 
    "20180518-00002", 
    "20180518-00003", 
    "20180518-00004"
];
unsortedArray.sort(function(obj1, obj2){
  if(sortedArrayField.indexOf(obj1.orderNo) != -1  && sortedArrayField.indexOf(obj2.orderNo) != -1){
  return sortedArrayField.indexOf(obj1.orderNo)- sortedArrayField.indexOf(obj2.orderNo);
} else if(sortedArrayField.indexOf(obj1.orderNo) != -1  && sortedArrayField.indexOf(obj2.orderNo) == -1){
  return 0;
} else {
   return 1;
}
});
console.log(unsortedArray);

Upvotes: 0

Nour
Nour

Reputation: 5889

If you know the field you need to sort based on it so @yadejo solution is right.

If you don't, try the following solution

    const unsortedArray = [
  {
    repId: '4',
    symbol: 'MSLA',
    orderNo: '20180518-00004'
  },
  {
    repId: '2',
    symbol: 'TSLA',
    orderNo: '20180518-00003'
  },
  {
    repId: '55',
    symbol: 'APPL',
    orderNo: '20180518-00001'
  },
  {
    repId: '22',
    symbol: 'FB',
    orderNo: '20180518-00002'
  }];

const sortedArrayField = [
  '20180518-00001',
  '20180518-00002',
  '20180518-00003',
  '20180518-00004'
];

const sortedArrayOfObject = [];

for (const sortedItem of sortedArrayField) {
  sortedArrayOfObject.push(unsortedArray.find(item => {
    for (const prop in item) {
      if (item[prop] === sortedItem) {
        return true;
      }
    }
    return false;
  }));
}

console.log(sortedArrayOfObject);

Upvotes: 1

yadejo
yadejo

Reputation: 1968

You can sort the array by using the index of the orderNo in the sorted array:

const unsortedArray = [
{
    repId: "4",
    symbol: "MSLA",
    orderNo: "20180518-00004"
},
{
    repId: "2",
    symbol: "TSLA",
    orderNo: "20180518-00003"
},
{
    repId: "55",
    symbol: "APPL",
    orderNo: "20180518-00001"
},
{
    repId: "22",
    symbol: "FB",
    orderNo: "20180518-00002"
}]

const sortedArrayField = [
    "20180518-00001", 
    "20180518-00002", 
    "20180518-00003", 
    "20180518-00004"
];


// Sort the array by index of orderNo in the sortedArray
unsortedArray.sort((x, y) => 
  sortedArrayField.indexOf(x.orderNo) - sortedArrayField.indexOf(y.orderNo)
);


console.log(unsortedArray);

Upvotes: 3

Related Questions