简体   繁体   中英

Sort an array in a peculiar order

I've been trying to figure out how to solve this problem but I can't seem to find the proper sorting order.

Instructions:

Write a program that orders a list of numbers in the following way:

3,-2,1,0,-1,0,-2,1 => -2,-1,-2,0,0,3,1,1

'use strict';
let myNumbers = '3,-2,1,0,-1,0,-2,1';
// I receive the input as a string and split and map it into an array
let myNumbers = gets().split(',').map(Number);

I've tried applying the sort() method in ascending order to all integers below zero and doing the opposite for those above but that's not quite the order in the expected output.

I've also attempted to splice the first array after applying sort() to 0 and then re-arrange the spliced part and concatenate it. However, that won't work with all test inputs.

Another example: 3,-12,0,0,13,5,1,0,-2 => -12,-2,0,0,0,3,13,5,1

What is the logic in this order? Thanks.

Because this sounds like the solution to a homework problem or something of the like, I'll let you write the code:) But the way I would do it is in one iteration through the array, create three separate arrays:

  1. Negative numbers
  2. 0s
  3. Positive numbers

Squish the arrays together without sorting and you have your O(N) solution.

So based on sketrik answer which covers the logic, this is the code:

 const myNumbers = '3,-2,1,0,-1,0,-2,1'; const arr = myNumbers.split(',').map(Number) const res = arr.filter(i => i < 0) .concat(arr.filter(i => i === 0)) .concat(arr.filter(i => i > 0)) console.log(res) 

This works thanks to two very basic JS methods of Array.prototype:

concat and filter . I could not explain them better than the documentation, check it out!

But basically, what I am doing is:

  1. find the chunk with negatives with arr.filter(i => i < 0)
  2. find the chunk with zeros with arr.filter(i => i === 0)
  3. find the chunk with positives with arr.filter(i => i > 0)
  4. concat them all into one array.

I am Neo.

 'use strict'; let myInput = '3,-2,1,0,-1,0,-2,1'; let myNumbers = myInput.split(',').map(Number); let negatives = []; let zeroes = []; let positives = []; for (const element of myNumbers) { if (element < 0) { negatives.push(element); } else if (element === 0) { zeroes.push(element); } else if (element > 0) { positives.push(element); } } let sortedArr = negatives.concat(zeroes, positives); console.log(sortedArr.join(',')); 

Logic or Typo?

"...ascending order to all integers below zero and doing the opposite for those above..."

Following what was posted in question the examples should be:

-2, -2, -1, 0, 0, 3, 1, 1 and -12, -2, 0, 0, 0, 13, 5, 3, 1

Zero and less ascending: -3, -2, -1, 0 . Greater than zero descending: 3, 2, 1

To get those results see Demo 1 .


Strictly going by the examples is simpler:

-2, -1, -2, 0, 0, 3, 1, 1 and -12, -2, 0, 0, 0, 3, 13, 5, 1

Group negative numbers, then zeros, and then positive numbers: [-][0][+] . No order within the three arrays is required. Order is only required for the three groups.

To get those results see Demo 2 .


Explanation

Demo 1

  1. First, sort array in ascending order:

    const ordered = array .sort ((current, next) => current - next);

  2. Next, find the index of the first number that's greater than 0, then extract all numbers beginning at that index and ending at the last number. Store the extracted array in a variable:

    const positive = ordered .splice (ordered .findIndex (number => number > 0));

  3. Finally, sort extracted array in descending order and then concatenate the extracted array to the end of the original array:

    return ordered .concat (positive.sort((current, next) => next - current));

Demo 2

  1. Create three new arrays returned by the filter() method: negative ( n < 0 ), zero ( n === 0) , and positive ( n > 0 ).

  2. Then concatenate them into one array:

    const negative = array.filter(number => number < 0);

    const zero = array.filter(number => number === 0);

    const positive = array.filter(number => number > 0);

    return negative.concat(zero, positive);


Demo 1

 const unorderedA = [3, -2, 1, 0, -1, 0, -2, 1]; const unorderedB = [3, -12, 0, 0, 13, 5, 1, 0, -2]; const illogical = array => { const ordered = array.sort((current, next) => current - next); const positive = ordered.splice(ordered.findIndex(number => number > 0)); return ordered.concat(positive.sort((current, next) => next - current)); }; // For demonstration purposes const log = data => { const string = Array.isArray(data) ? `[${data.join(', ')}]` : data; return console.log(string); }; log(illogical(unorderedA)); log(illogical(unorderedB)); 

Demo 2

 const unorderedA = [3, -2, 1, 0, -1, 0, -2, 1]; const unorderedB = [3, -12, 0, 0, 13, 5, 1, 0, -2]; const illogical = array => { const negative = array.filter(number => number < 0); const zero = array.filter(number => number === 0); const positive = array.filter(number => number > 0); return negative.concat(zero, positive); }; // For demonstration purposes const log = data => { const string = Array.isArray(data) ? `[${data.join(', ')}]` : data; return console.log(string); }; log(illogical(unorderedA)); log(illogical(unorderedB)); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM