0

I have an array e.g. 3,4,3,1,5

Sorting in Ascending or descending order gives 1,3,3,4,5 or 5,4,3,3,1.

I need the original order e.g. 3,3,4,1,5

underscoreJs has the groupBy method, but that splits the array up into the groups.

Any ideas?

8
  • what qualifies a group? Commented Nov 12, 2019 at 12:35
  • questionData.questions = _.chain(questionData.questions) .sortBy('category') .each(function (resultNew, indexNew) { resultNew.order = indexNew + 1; }) .sortBy('order') .value(); Commented Nov 12, 2019 at 12:37
  • Clone the original array!? Commented Nov 12, 2019 at 12:37
  • 1
    This sounds like an X-Y problem, especially given the extra context in that code comment. You're probably not actually sorting just numbers, are you? Commented Nov 12, 2019 at 12:38
  • E.g. we could replace the sortBy('category') with groupBy('category'). but that changes the format of the output. Commented Nov 12, 2019 at 12:38

3 Answers 3

1

You can do

const arr = [3, 4, 3, 1, 5];

const result = arr.sort((a, b) => a === b || arr.indexOf(a) - arr.indexOf(b));

console.log(result);
Sign up to request clarification or add additional context in comments.

6 Comments

questionData.questions = _.chain(questionData.questions) .sortBy('category') .each(function (resultNew, indexNew) { resultNew.order = indexNew + 1; }) .sortBy('order') .value();
I'm not actually sorting on 3,4,3,1,5 , I'm sorting on a 'Category' property of an array which has those values. How can this be applied the the above?
I guess questionData.questions.sort((a, b) => a.category === b.category || questionData.questions.indexOf(a) - questionData.questions.indexOf(b));
That hasn't changed hasn't grouped them at all.
Oh, and groupBy also orders on Category, which I don't want it to do. I need it to keep the existing order, just group them together.
|
1

If you want to sort the array in place, you can get the priority for each item and sort it using the priority object

let array = [3, 4, 3, 1, 5],
    index = 0,
    priority = {};
      
array.forEach(n => priority[n] = priority[n] || ++index);
array.sort((a, b) => priority[a] - priority[b])

console.log(array)

If you want a new array, you could create a counter object which counts the occurrence. Then, create another array based on the count of each number

const 
    array = [3, 4, 3, 1, 5],
    counter = array.reduce((acc, n) => acc.set(n, acc.get(n) + 1 || 1), new Map),
    output = Array.from(counter).flatMap(([n, count]) => Array(count).fill(n))

console.log(output)

Comments

0

Here is my quite long-winded solution which works but will could do with refining.

             var tempQuestions = [];

            // For each Question.
            _.each(questionData.questions, function (resultCategory, indexCategory) {
                // Get other Question for the same Category, and push to new Array.
                tempQuestions.push(_.filter(questionData.questions, function (num) {
                    return num.category === resultCategory.category;
                }));
                // Remove all Question for the processes Cateogory (these are now stored in the tempQuestions)
                questionData.questions = _.filter(questionData.questions, function (item) {
                    return item.category !== resultCategory.category;
                });
            });

            // The above processing will create some unwanted blank arrays, remove them.
            tempQuestions = _.filter(tempQuestions, function (num) {
                return num.length !== 0;
            });

            // Flatten the array structure to match the original.
            questionData.questions = _(tempQuestions).chain()
                .zip()
                .flatten()
                .value();

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.