daydreamer
daydreamer

Reputation: 92019

Produce new array where all positive comes first, then negative or zero but in same order

This is problem from Scala for the Impatient, chapter of Arrays stated as

Given an array of integers, produce a new array that contains all positive values of the original array, in their original order, followed by all values that are zero or negative, in their original order.

My attempt is

scala> val b = Array(-1, 2,3,4, -10, 0, -12)
b: Array[Int] = Array(-1, 2, 3, 4, -10, 0, -12)

scala> val(positive, negative) = b partition(_ > 0)
positive: Array[Int] = Array(2, 3, 4)
negative: Array[Int] = Array(-1, -10, 0, -12)

scala> positive ++ negative
res11: Array[Int] = Array(2, 3, 4, -1, -10, 0, -12)

Can I do this better in one line? I am not sure

Upvotes: 4

Views: 770

Answers (5)

Ava
Ava

Reputation: 838

We can assign 1 if value is positive and 0 otherwise using max(0, x.sign) to distinguish between them. Because we want positive values first (descending order) we prepend our max with a minus. The solution then simplifies to:

b.sortBy(x => -max(0, x.sign))

Sorting in Scala is stable so the original order will persist.

Upvotes: 0

Angel
Angel

Reputation: 1

b.sortWith((l, r) => if(l > 0 && r < 1) true else false)

Upvotes: 0

Artem Vlasenko
Artem Vlasenko

Reputation: 125

Seems the very simple if you use the filters. My version:

def result(a: Array[Int]): Array[Int] = a.filter(_ > 0) ++ a.filter(_ <= 0)

Upvotes: 2

Eugene Osmet
Eugene Osmet

Reputation: 21

b.sorted(Ordering.by((_: Int) <= 0))

Method sorted returns the sorted array according to an Ordering (which says that positive numbers have lower order than zero or negative), without modifying the original array.

Upvotes: 2

elm
elm

Reputation: 20415

Consider filter and filterNot as follows,

b.filter(_ > 0) ++ b.filterNot(_ > 0)

Upvotes: 6

Related Questions