2

Due to badly written code. I have to sort an array and base on that sorting, sort another array in the same order. E.g:

foo =[ ['tom', 20, {teacher: 'may', class: 'math'}],
       ['Ann', 21, {teacher: 'Joe', class: 'CS'}],
       ['tony', 22, {teacher: 'may', class: 'math'}]
     ]
bar = [{extraPara: 'ran1', Sequence 2},
       {extraPara: 'ran2', Sequence 1},
       {extraPara: 'ran3', Sequence 3},
      ]

I want to sort bar with Sequence. And I want to sort foo base on that sequence too. Basically both array should be in one big array, but because of bad coding, it is separated. However I do not have time to re write the whole structure.

What is the most efficient way to do this?

I can easily sort bar by:

 bar = _.sortBy(bar, function(item) {return item.Sequence})

The only way I know how to do it is write the sorting algorithm myself, and whenever I change the ordering of bar I will use the index and do the same for foo. However that sounds very inefficient and readability is really bad

any tips?

4
  • Is there a "foreign key" between the two arrays? Commented Jun 29, 2017 at 19:57
  • what means "Basically both array should be in one big array"? can you add an example? Commented Jun 29, 2017 at 19:58
  • I would create a new array, add the keys as the elements from one array and then their corresponding value from the other array, then sort based of key/values whichever you'd prefer. Of course this is going to add n operations to your sort so nothing will be faster than writing a sort by hand as you suggest. Commented Jun 29, 2017 at 20:00
  • 'Should have been' cause basically they are missing 'foreign key' as kramb mention. The relationship between the two array is missing, they basically should be one array as in first row should be something like 'tom', 20, { teacher: 'may', class: 'math', extraPara: 'ran1', Sequence 2 }. But it's too late now, lots of other places use these two arrays seperately. For now as a hotfix I need to sort both array base on the Sequence Commented Jun 29, 2017 at 20:05

2 Answers 2

3

You could use a helper array with the indices and sort them with sequence and map the foo array with the sorted indices as new sorted array.

var foo = [['tom', 20, { teacher: 'may', class: 'math' }], ['Ann', 21, { teacher: 'Joe', class: 'CS' }], ['tony', 22, { teacher: 'may', class: 'math' }]],
    bar = [{ extraPara: 'ran1', Sequence: 2 }, { extraPara: 'ran2', Sequence: 1 }, { extraPara: 'ran3', Sequence: 3 }],
    order = bar.map(function (_, i) {
        return i;
    }).sort(function (a, b) {
        return bar[a].Sequence - bar[b].Sequence;
    }),
    result = order.map(function (i) {
        return foo[i];
    });

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

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

Comments

2

Schwartzian to the rescue!

foo =[ ['tom', 20, {teacher: 'may', class: 'math'}],
       ['Ann', 21, {teacher: 'Joe', class: 'CS'}],
       ['tony', 22, {teacher: 'may', class: 'math'}]
     ]
bar = [{extraPara: 'ran1', Sequence: 2},
       {extraPara: 'ran2', Sequence: 1},
       {extraPara: 'ran3', Sequence: 3},
      ]

//

res = foo
  .map((x, i) => [bar[i].Sequence, x])
  .sort((x, y) => x[0] - y[0])
  .map(x => x[1]);

console.log(res)

generic function:

let sortBy = (a, key) => a
    .map((x, i) => [key(x, i), x])
    .sort((x, y) => (x[0] > y[0]) - (x[0] < y[0]))
    .map(x => x[1]);

res = sortBy(foo, (_, i) => bar[i].Sequence)

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.