1

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.

2
  • You need to specify what you mean by "sorted field". Do you know when you're given the list which property they map to? Could keys in the same list map to different properties? Can a key match multiple objects? What's the exact criteria for matching a key against an object? It's not clear with your single input example. Commented May 18, 2018 at 20:02
  • Also, maybe post what you already have, since "elegant" is pretty subjective (and likely to be closed) Commented May 18, 2018 at 20:05

4 Answers 4

3

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

Sign up to request clarification or add additional context in comments.

Comments

1

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

2 Comments

This gets tricky when multiple key's in the objects have the same value. But in that case, there really is no way to sort the items :)
Yes i guess you are right, in that case he should know what is the property he will sort based on it. Nice catch :).
0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.