Sort Alphanumeric Array, Consecutive Numbers Should Reside at Last

Sort alphanumeric array, consecutive numbers should reside at last

Here's a solution that works for your case :

The expected result is :

  • letters first ;
  • then numbers ;
  • then others ;

Here's a way to do it.

// Works with both arrays
var array = ["1", "b", "a", "z", "3", "!"]
//var array = ["1", "b", "A", "Z", "3", "!"]

func isLetter(char: String) -> Bool {
return ("a"..."z").contains(char) || ("A"..."Z").contains(char)
}

func isNumber(char: String) -> Bool {
return Int(char) != nil
}

let letters = array.filter(isLetter).sort{$0.lowercaseString < $1.lowercaseString}
let numbers = array.filter(isNumber).sort{Int($0) < Int($1)}
let others = Array(Set(array).subtract(letters).subtract(numbers)).sort{$0 < $1}

let sortedArray = letters + numbers + others

The first array would be

["a", "b", "z", "1", "3", "!"]

The second would be

["A", "b", "Z", "1", "3", "!"]

It does what you want. Include unit tests and wrap that inside a method and you're good to go. Buuuut, it's not "clean" at all.

How to sort an alphanumeric array in ruby

You can pass a block to the sort function to custom sort it. In your case you will have a problem because your numbers aren't zero padded, so this method zero pads the numerical parts, then sorts them, resulting in your desired sort order.

a.sort { |a,b|
ap = a.split('_')
a = ap[0] + "%05d" % ap[1] + "%05d" % ap[2]
bp = b.split('_')
b = bp[0] + "%05d" % bp[1] + "%05d" % bp[2]
b <=> a
}

Sorting numbers after letters in alphabetical order

It's unclear what you want, because your verbal description doesn't match your shown output. It's easy to achieve the shown output from the given input:

let tricks = [ "360", "540", "720", "Blunt", "Nose Grind", "Method Air", "360 Mute Grab", "Japan Air"]
func startsWithANumber(_ s:String) -> Bool {
return "0123456789".contains(s.first!)
}
let nonnumbers = tricks.filter {!startsWithANumber($0)}
let numbers = tricks.filter {startsWithANumber($0)}
let result = nonnumbers + numbers.sorted()
// ["Blunt", "Nose Grind", "Method Air", "Japan Air", "360", "360 Mute Grab", "540", "720"]

But whether that correctly covers all possible sets of input is impossible to say, because you have not described your desired output with any clarity or rigor.

fill gap between alphanumeric array elements

You can iterate through your array once to collect the following information:

  • what alpha parts do you have
  • what are left and right (min and max) boundaries for each alpha part

In your example, after first iteration we will know that there are two alphas:

  • A, starting from 1 and going up to 5
  • E, starting from 1 and going up to 6

Now, you can just generate the answer.

Demo:

var sourceYours = ['A1', 'A2', 'A5', 'E1', 'E4', 'E6']var sourceComplex = ['A1', 'A2', 'A5', 'E1', 'E4', 'E6', 'D2', 'D4', 'E7'];
console.log(fillGaps(sourceYours));console.log(fillGaps(sourceComplex));
function fillGaps(arr) { var alphas = {}; arr.forEach(function(x) { var alpha = x.replace(/\d/, ""), numeric = +x.replace(/\D/, ""); if (!alphas[alpha]) { alphas[alpha] = { min: numeric, max: numeric }; } else { alphas[alpha].min = Math.min(alphas[alpha].min, numeric); alphas[alpha].max = Math.max(alphas[alpha].max, numeric); } }); var result = []; for (var alpha in alphas) { for (var num = alphas[alpha].min; num <= alphas[alpha].max; num++) { result.push(alpha + num); } } return result;}

Sort mixed alpha/numeric array

var reA = /[^a-zA-Z]/g;var reN = /[^0-9]/g;
function sortAlphaNum(a, b) { var aA = a.replace(reA, ""); var bA = b.replace(reA, ""); if (aA === bA) { var aN = parseInt(a.replace(reN, ""), 10); var bN = parseInt(b.replace(reN, ""), 10); return aN === bN ? 0 : aN > bN ? 1 : -1; } else { return aA > bA ? 1 : -1; }}console.log(["A1", "A10", "A11", "A12", "A2", "A3", "A4", "B10", "B2", "F1", "F12", "F3"].sort(sortAlphaNum))

Sort on a string that may contain a number

The Alphanum Algorithm

From the website

"People sort strings with numbers differently than software. Most sorting algorithms compare ASCII values, which produces an ordering that is inconsistent with human logic. Here's how to fix it."

Edit: Here's a link to the Java Comparator Implementation from that site.

Idiomatic way to generate a random alphanumeric string in Kotlin

Assuming you have a specific set of source characters (source in this snippet), you could do this:

val source = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
java.util.Random().ints(outputStrLength, 0, source.length)
.asSequence()
.map(source::get)
.joinToString("")

Which gives strings like "LYANFGNPNI" for outputStrLength = 10.

The two important bits are

  1. Random().ints(length, minValue, maxValue) which produces a stream of length random numbers each from minValue to maxValue-1, and
  2. asSequence() which converts the not-massively-useful IntStream into a much-more-useful Sequence<Int>.

Natural sort order string comparison in Java - is one built in?

In java the "natural" order meaning is "lexicographical" order, so there is no implementation in the core like the one you're looking for.

There are open source implementations.

Here's one:

NaturalOrderComparator.java

Make sure you read the:

Cougaar Open Source License

I hope this helps!

Collections.sort with multiple fields

Do you see anything wrong with the code?

Yes. Why are you adding the three fields together before you compare them?

I would probably do something like this: (assuming the fields are in the order you wish to sort them in)

@Override public int compare(final Report record1, final Report record2) {
int c;
c = record1.getReportKey().compareTo(record2.getReportKey());
if (c == 0)
c = record1.getStudentNumber().compareTo(record2.getStudentNumber());
if (c == 0)
c = record1.getSchool().compareTo(record2.getSchool());
return c;
}


Related Topics



Leave a reply



Submit