Sort a list of object identifiers: Difference between revisions

m
m (→‎{{header|Sidef}}: simpler code)
m (→‎{{header|Wren}}: Minor tidy)
(107 intermediate revisions by 45 users not shown)
Line 1:
{{draft task|Sorting Algorithms}}
[[Category:Sorting]]
{{Sorting Algorithm}}
 
[[wp:Object identifier|Object identifiers (OID)]] are strings used to identify objects in network data.
 
{{task heading}}
 
;Task:
Show how to sort a list of OIDs, in their natural sort order.
 
Line 10 ⟶ 12:
 
* An OID consists of one or more non-negative integers in base 10, separated by dots. It starts and ends with a number.
* Their natural sort order is [[wp:LexicographicalLexicographical_order|lexicographical]] with regard to the dot-separated fields, using numeric comparison between fields.
 
{{task heading|Test case}}
 
:::: {| class="wikitable"
|-
! Input ''(list of strings)''
Line 42 ⟶ 44:
<hr>
 
=={{header|C++11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V data = [
{{update|C++|the format description and test-case in the task description have been updated}}
‘1.3.6.1.4.1.11.2.17.19.3.4.0.10’,
‘1.3.6.1.4.1.11.2.17.5.2.0.79’,
‘1.3.6.1.4.1.11.2.17.19.3.4.0.4’,
‘1.3.6.1.4.1.11150.3.4.0.1’,
‘1.3.6.1.4.1.11.2.17.19.3.4.0.1’,
‘1.3.6.1.4.1.11150.3.4.0’
]
 
V delim = ‘.’ // to get round ‘bug in MSVC 2017’[https://developercommunity.visualstudio.com/t/bug-with-operator-in-c/565417]
<lang Cpp>#include <string>
 
L(s) sorted(data, key' x -> x.split(:delim).map(Int))
print(s)</syntaxhighlight>
 
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE PTR="CARD"
 
PROC PrintArray(PTR ARRAY a INT size)
INT i
 
FOR i=0 TO size-1
DO
PrintE(a(i))
OD
RETURN
 
INT FUNC Decode(CHAR ARRAY s INT ARRAY a)
INT count
BYTE i,begin,end
CHAR ARRAY tmp(10)
 
count=0 i=1
WHILE i<=s(0)
DO
begin=i
WHILE i<=s(0) AND s(i)#'.
DO i==+1 OD
end=i-1
IF i<s(0) THEN i==+1 FI
SCopyS(tmp,s,begin,end)
a(count)=ValI(tmp)
count==+1
OD
RETURN (count)
 
INT FUNC Compare(CHAR ARRAY s1,s2)
INT ARRAY a1(20),a2(20)
INT c1,c2,res
BYTE i
 
c1=Decode(s1,a1)
c2=Decode(s2,a2)
 
i=0
DO
IF i=c1 AND i=c2 THEN
RETURN (0)
ELSEIF i=c1 THEN
RETURN (-1)
ELSEIF i=c2 THEN
RETURN (1)
FI
 
IF a1(i)<a2(i) THEN
RETURN (-1)
ELSEIF a1(i)>a2(i) THEN
RETURN (1)
FI
i==+1
OD
RETURN (0)
 
PROC Sort(PTR ARRAY a INT size)
INT i,j,minpos
CHAR ARRAY tmp
 
FOR i=0 TO size-2
DO
minpos=i
FOR j=i+1 TO size-1
DO
IF Compare(a(minpos),a(j))>0 THEN
minpos=j
FI
OD
IF minpos#i THEN
tmp=a(i)
a(i)=a(minpos)
a(minpos)=tmp
FI
OD
RETURN
 
PROC Main()
DEFINE SIZE="6"
PTR ARRAY a(SIZE)
 
a(0)="1.3.6.1.4.1.11.2.17.19.3.4.0.10"
a(1)="1.3.6.1.4.1.11.2.17.5.2.0.79"
a(2)="1.3.6.1.4.1.11.2.17.19.3.4.0.4"
a(3)="1.3.6.1.4.1.11150.3.4.0.1"
a(4)="1.3.6.1.4.1.11.2.17.19.3.4.0.1"
a(5)="1.3.6.1.4.1.11150.3.4.0"
 
PrintE("Array before sort:")
PrintArray(a,SIZE) PutE()
Sort(a,SIZE)
PrintE("Array after sort:")
PrintArray(a,SIZE)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Sort_a_list_of_object_identifiers.png Screenshot from Atari 8-bit computer]
<pre>
Array before sort:
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11150.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11150.3.4.0
 
Array after sort:
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Ada}}==
 
{{works with|Ada|Ada|2012}}
 
<syntaxhighlight lang="ada">with Ada.Containers.Generic_Array_Sort;
with Ada.Strings.Fixed;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO;
with Ada.Unchecked_Deallocation;
 
procedure Sort_List_Identifiers is
type Natural_Array is array (Positive range <>) of Natural;
type Unbounded_String_Array is array(Positive range <>) of Unbounded_String;
 
function To_Natural_Array(input : in String) return Natural_Array
is
target : Natural_Array(1 .. Ada.Strings.Fixed.Count(input, ".") + 1);
from : Natural := input'First;
to : Natural := Ada.Strings.Fixed.Index(input, ".");
index : Positive := target'First;
begin
while to /= 0 loop
target(index) := Natural'Value(input(from .. to - 1));
from := to + 1;
index := index + 1;
to := Ada.Strings.Fixed.Index(input, ".", from);
end loop;
target(index) := Natural'Value(input(from .. input'Last));
return target;
end To_Natural_Array;
 
function Lesser(Left, Right : in Unbounded_String) return Boolean is
begin
return To_Natural_Array(To_String(Left)) < To_Natural_Array(To_String(Right));
end Lesser;
 
procedure Sort is new Ada.Containers.Generic_Array_Sort
(Index_Type => Positive,
Element_Type => Unbounded_String,
Array_Type => Unbounded_String_Array,
"<" => Lesser);
 
table : Unbounded_String_Array :=
(To_Unbounded_String("1.3.6.1.4.1.11.2.17.19.3.4.0.10"),
To_Unbounded_String("1.3.6.1.4.1.11.2.17.5.2.0.79"),
To_Unbounded_String("1.3.6.1.4.1.11.2.17.19.3.4.0.4"),
To_Unbounded_String("1.3.6.1.4.1.11150.3.4.0.1"),
To_Unbounded_String("1.3.6.1.4.1.11.2.17.19.3.4.0.1"),
To_Unbounded_String("1.3.6.1.4.1.11150.3.4.0"));
begin
Sort(table);
for element of table loop
Ada.Text_IO.Put_Line(To_String(element));
end loop;
end Sort_List_Identifiers;</syntaxhighlight>
{{out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|AppleScript}}==
===Vanilla===
Place the call to the sort handler in a <tt>considering numeric strings</tt> statement.
<syntaxhighlight lang="applescript">(* Shell sort
Algorithm: Donald Shell, 1959.
*)
 
on ShellSort(theList, l, r)
script o
property lst : theList
end script
set listLength to (count theList)
if (listLength > 1) then
-- Convert negative and/or transposed range indices.
if (l < 0) then set l to listLength + l + 1
if (r < 0) then set r to listLength + r + 1
if (l > r) then set {l, r} to {r, l}
-- Do the sort.
set stepSize to (r - l + 1) div 2
repeat while (stepSize > 0)
repeat with i from (l + stepSize) to r
set currentValue to item i of o's lst
repeat with j from (i - stepSize) to l by -stepSize
set thisValue to item j of o's lst
if (currentValue < thisValue) then
set item (j + stepSize) of o's lst to thisValue
else
set j to j + stepSize
exit repeat
end if
end repeat
if (j < i) then set item j of o's lst to currentValue
end repeat
set stepSize to (stepSize / 2.2) as integer
end repeat
end if
return -- nothing. The input list has been sorted in place.
end ShellSort
property sort : ShellSort
 
-- Test code: sort items 1 thru -1 (ie. all) of a list of strings, treating numeric portions numerically.
set theList to {"1.3.6.1.4.1.11.2.17.19.3.4.0.10", "1.3.6.1.4.1.11.2.17.5.2.0.79", "1.3.6.1.4.1.11.2.17.19.3.4.0.4", ¬
"1.3.6.1.4.1.11150.3.4.0.1", "1.3.6.1.4.1.11.2.17.19.3.4.0.1", "1.3.6.1.4.1.11150.3.4.0"}
considering numeric strings
sort(theList, 1, -1)
end considering
return theList</syntaxhighlight>
 
{{output}}
<pre>{"1.3.6.1.4.1.11.2.17.5.2.0.79", "1.3.6.1.4.1.11.2.17.19.3.4.0.1", "1.3.6.1.4.1.11.2.17.19.3.4.0.4", "1.3.6.1.4.1.11.2.17.19.3.4.0.10", "1.3.6.1.4.1.11150.3.4.0", "1.3.6.1.4.1.11150.3.4.0.1"}</pre>
 
===ASObjC===
Use the <tt>localizedStandardCompare:</tt> string comparison method.
<syntaxhighlight lang="applescript">use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
 
set theList to {"1.3.6.1.4.1.11.2.17.19.3.4.0.10", "1.3.6.1.4.1.11.2.17.5.2.0.79", "1.3.6.1.4.1.11.2.17.19.3.4.0.4", ¬
"1.3.6.1.4.1.11150.3.4.0.1", "1.3.6.1.4.1.11.2.17.19.3.4.0.1", "1.3.6.1.4.1.11150.3.4.0"}
 
set theArray to current application's class "NSMutableArray"'s arrayWithArray:(theList)
set theDescriptor to current application's class "NSSortDescriptor"'s sortDescriptorWithKey:("self") ¬
ascending:(true) selector:("localizedStandardCompare:")
tell theArray to sortUsingDescriptors:({theDescriptor})
return theArray as list</syntaxhighlight>
 
{{output}}
<pre>{"1.3.6.1.4.1.11.2.17.5.2.0.79", "1.3.6.1.4.1.11.2.17.19.3.4.0.1", "1.3.6.1.4.1.11.2.17.19.3.4.0.4", "1.3.6.1.4.1.11.2.17.19.3.4.0.10", "1.3.6.1.4.1.11150.3.4.0", "1.3.6.1.4.1.11150.3.4.0.1"}</pre>
 
===Functional===
 
As a composition of pure functions:
 
<syntaxhighlight lang="applescript">------------- SORTED LIST OF OBJECT IDENTIFIERS ------------
 
-- sortedIdentifiers :: [String] -> [String]
on sortedIdentifiers(xs)
script listCompare
on |λ|(x, y)
script go
on |λ|(a, xy)
if 0 ≠ a then
a
else
compare(|1| of xy, |2| of xy)
end if
end |λ|
end script
foldl(go, 0, zip(x, y))
end |λ|
end script
map(intercalate("."), ¬
sortBy(listCompare, ¬
map(compose(curry(my map)'s ¬
|λ|(my readint), splitOn(".")), xs)))
end sortedIdentifiers
 
 
---------------------------- TEST --------------------------
on run
unlines(sortedIdentifiers({¬
"1.3.6.1.4.1.11.2.17.19.3.4.0.10", ¬
"1.3.6.1.4.1.11.2.17.5.2.0.79", ¬
"1.3.6.1.4.1.11.2.17.19.3.4.0.4", ¬
"1.3.6.1.4.1.11150.3.4.0.1", ¬
"1.3.6.1.4.1.11.2.17.19.3.4.0.1", ¬
"1.3.6.1.4.1.11150.3.4.0"}))
end run
 
 
--------------------- LIBRARY FUNCTIONS --------------------
 
-- Tuple (,) :: a -> b -> (a, b)
on Tuple(a, b)
-- Constructor for a pair of values, possibly of two different types.
{type:"Tuple", |1|:a, |2|:b, length:2}
end Tuple
 
 
-- compare :: a -> a -> Ordering
on compare(a, b)
if a < b then
-1
else if a > b then
1
else
0
end if
end compare
 
 
-- compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
on compose(f, g)
script
property mf : mReturn(f)
property mg : mReturn(g)
on |λ|(x)
mf's |λ|(mg's |λ|(x))
end |λ|
end script
end compose
 
 
-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
set lng to length of xs
set acc to {}
tell mReturn(f)
repeat with i from 1 to lng
set acc to acc & (|λ|(item i of xs, i, xs))
end repeat
end tell
return acc
end concatMap
 
 
-- curry :: ((a, b) -> c) -> a -> b -> c
on curry(f)
script
on |λ|(a)
script
on |λ|(b)
|λ|(a, b) of mReturn(f)
end |λ|
end script
end |λ|
end script
end curry
 
 
-- drop :: Int -> [a] -> [a]
-- drop :: Int -> String -> String
on drop(n, xs)
set c to class of xs
if script is not c then
if string is not c then
if n < length of xs then
items (1 + n) thru -1 of xs
else
{}
end if
else
if n < length of xs then
text (1 + n) thru -1 of xs
else
""
end if
end if
else
take(n, xs) -- consumed
return xs
end if
end drop
 
 
-- findIndices :: (a -> Bool) -> [a] -> [Int]
on findIndices(p, xs)
-- List of zero-based indices of
-- any matches for p in xs.
script
property f : mReturn(p)
on |λ|(x, i, xs)
if f's |λ|(x, i, xs) then
{i - 1}
else
{}
end if
end |λ|
end script
concatMap(result, xs)
end findIndices
 
 
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
 
 
-- fst :: (a, b) -> a
on fst(tpl)
if class of tpl is record then
|1| of tpl
else
item 1 of tpl
end if
end fst
 
 
-- intercalate :: String -> [String] -> String
on intercalate(delim)
script
on |λ|(xs)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, delim}
set s to xs as text
set my text item delimiters to dlm
s
end |λ|
end script
end intercalate
 
 
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
-- The list obtained by applying f
-- to each element of xs.
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
 
 
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
-- 2nd class handler function lifted into 1st class script wrapper.
if script is class of f then
f
else
script
property |λ| : f
end script
end if
end mReturn
 
 
-- Returns a sequence-matching function for findIndices etc
-- matching :: [a] -> (a -> Int -> [a] -> Bool)
-- matching :: String -> (Char -> Int -> String -> Bool)
on matching(pat)
if class of pat is text then
set xs to characters of pat
else
set xs to pat
end if
set lng to length of xs
set bln to 0 < lng
if bln then
set h to item 1 of xs
else
set h to missing value
end if
script
on |λ|(x, i, src)
(h = x) and xs = ¬
(items i thru min(length of src, -1 + lng + i) of src)
end |λ|
end script
end matching
 
 
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
 
 
-- partition :: (a -> Bool) -> [a] -> ([a], [a])
on partition(f, xs)
tell mReturn(f)
set ys to {}
set zs to {}
repeat with x in xs
set v to contents of x
if |λ|(v) then
set end of ys to v
else
set end of zs to v
end if
end repeat
end tell
Tuple(ys, zs)
end partition
 
 
-- readInt :: String -> Int
on readint(s)
s as integer
end readint
 
 
-- snd :: (a, b) -> b
on snd(tpl)
if class of tpl is record then
|2| of tpl
else
item 2 of tpl
end if
end snd
 
 
-- Enough for small scale sorts.
-- Use instead sortOn (Ord b => (a -> b) -> [a] -> [a])
-- which is equivalent to the more flexible sortBy(comparing(f), xs)
-- and uses a much faster ObjC NSArray sort method
-- sortBy :: (a -> a -> Ordering) -> [a] -> [a]
on sortBy(f, xs)
if length of xs > 1 then
set h to item 1 of xs
set f to mReturn(f)
script
on |λ|(x)
f's |λ|(x, h) ≤ 0
end |λ|
end script
set lessMore to partition(result, rest of xs)
sortBy(f, |1| of lessMore) & {h} & ¬
sortBy(f, |2| of lessMore)
else
xs
end if
end sortBy
 
 
-- splitOn :: [a] -> [a] -> [[a]]
-- splitOn :: String -> String -> [String]
on splitOn(pat)
script
on |λ|(src)
if class of src is text then
set {dlm, my text item delimiters} to ¬
{my text item delimiters, pat}
set xs to text items of src
set my text item delimiters to dlm
return xs
else
set lng to length of pat
script residue
on |λ|(a, i)
Tuple(fst(a) & ¬
{init(items snd(a) thru (i) of src)}, lng + i)
end |λ|
end script
set tpl to foldl(residue, ¬
Tuple({}, 1), findIndices(matching(pat), src))
return fst(tpl) & {drop(snd(tpl) - 1, src)}
end if
end |λ|
end script
end splitOn
 
 
-- unlines :: [String] -> String
on unlines(xs)
-- A single string formed by the intercalation
-- of a list of strings with the newline character.
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set s to xs as text
set my text item delimiters to dlm
s
end unlines
 
 
-- zip :: [a] -> [b] -> [(a, b)]
on zip(xs, ys)
zipWith(my Tuple, xs, ys)
end zip
 
 
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
set lng to min(length of xs, length of ys)
set lst to {}
if 1 > lng then
return {}
else
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, item i of ys)
end repeat
return lst
end tell
end if
end zipWith</syntaxhighlight>
{{Out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">lst: [
"1.3.6.1.4.1.11.2.17.19.3.4.0.10"
"1.3.6.1.4.1.11.2.17.5.2.0.79"
"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
"1.3.6.1.4.1.11150.3.4.0.1"
"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
"1.3.6.1.4.1.11150.3.4.0"
]
 
print.lines arrange lst 'x ->
sum map.with:'i to [:integer] split.by:"." x 'z ->
z * 10^(20-i)</syntaxhighlight>
 
{{out}}
 
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
=={{header|ATS}}==
 
<syntaxhighlight lang="ats">
(* Sort a list of object identifiers (OID). *)
 
#include "share/atspre_staload.hats"
staload UN = "prelude/SATS/unsafe.sats"
 
%{^
#include <alloca.h> /* ATS2 exceptions require alloca(3). */
%}
 
#define NIL list_nil ()
#define :: list_cons
 
infixl ( :: ) :::
#define VNIL list_vt_nil ()
#define ::: list_vt_cons
 
exception Exc_not_an_oid of (string, string)
exception Exc_internal_error of (string)
macdef not_an_oid (s) = $raise Exc_not_an_oid ($mylocation, ,(s))
macdef internal_error () = $raise Exc_internal_error ($mylocation)
 
fn
oid_explode
{n : int}
(s : string n)
:<!exnwrt> List0_vt String1 =
let
fun
loop {i : nat | i <= n}
.<n - i>.
(lst : &list_vt (String1, 0) >> List0_vt String1,
i : size_t i)
:<!exnwrt> void =
if ~string_is_atend (s, i) then
let
fun
scan_number
{j : int | i <= j; j <= n}
.<n - j>.
(j : size_t j)
:<> [j : int | i <= j; j <= n]
size_t j =
if string_is_atend (s, j) then
j
else if ~isdigit s[j] then
j
else
scan_number (succ j)
 
val j = scan_number i
in
if j = i then
not_an_oid s
else if string_is_atend (s, j) then
let
val t =
strnptr2string (string_make_substring (s, i, j - i))
val+ ~ VNIL = lst
in
lst := t ::: VNIL
end
else if s[j] <> '.' then
not_an_oid s
else if string_is_atend (s, succ j) then
not_an_oid s
else
let
val+ ~ VNIL = lst
val t =
strnptr2string
(string_make_substring (s, i, j - i))
val () = lst := t ::: VNIL
val+ @ _ ::: tail = lst
val () = loop (tail, succ j)
prval () = fold@ lst
in
end
end
 
prval () = lemma_string_param s
 
var lst : List0_vt String1 = VNIL
in
if string_is_empty s then
not_an_oid s;
loop (lst, i2sz 0);
lst
end
 
fn
oid_field_cmp
(x : String0,
y : String0)
:<!exn> int =
let
fun
to_number {n : nat}
{i : nat | i <= n}
.<n - i>.
(s : string n,
i : size_t i,
accum : ullint)
:<!exn> ullint =
if string_is_atend (s, i) then
accum
else if ~isdigit s[i] then
internal_error ()
else
let
val digit = $UN.cast{ullint} s[i] - $UN.cast '0'
in
to_number (s, succ i, (10ULL * accum) + digit)
end
 
val nx = to_number (x, i2sz 0, 0ULL)
and ny = to_number (y, i2sz 0, 0ULL)
in
compare (nx, ny)
end
 
fn
oid_cmp (x : String0,
y : String0)
:<!exnwrt> int =
let
fun
loop {m, n : nat}
.<m, n>.
(xs : list (String1, m),
ys : list (String1, n))
:<!exnwrt> int =
case+ ys of
| NIL => if iseqz xs then 0 else 1
| yhead :: ytail =>
begin
case+ xs of
| NIL => ~1
| xhead :: xtail =>
let
val cmp = oid_field_cmp (xhead, yhead)
in
if cmp = 0 then
loop (xtail, ytail)
else
cmp
end
end
 
val xs = list_vt2t (oid_explode x)
and ys = list_vt2t (oid_explode y)
in
loop (xs, ys)
end
 
fn
oid_list_sort
{n : int}
(lst : list (String0, n))
:<!exnwrt> list_vt (String0, n) =
list_mergesort_fun<String0>
(lst, lam (x, y) => $effmask_all oid_cmp (x, y))
 
implement
main0 () =
try
let
val oid_list =
$list ("1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0")
val oid_sorted = list_vt2t (oid_list_sort oid_list)
 
var p : List0 String0
in
for (p := oid_sorted; isneqz p; p := list_tail p)
println! (list_head p)
end
with
| ~ Exc_not_an_oid (loc, s) =>
begin
println! ("Not a UID: \"", s, "\" (exception raised at ", loc, ")");
exit 1
end
| ~ Exc_internal_error loc =>
begin
println! ("Internal error (exception raised at ", loc, ")");
exit 1
end
</syntaxhighlight>
 
{{out}}
<pre>
$ patscc -DATS_MEMALLOC_GCBDW oid_sort.dats -lgc && ./a.out
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">; based on http://www.rosettacode.org/wiki/Sorting_algorithms/Quicksort#AutoHotkey
OidQuickSort(a, Delim:=".", index:=1){
if (a.Count() <= 1)
return a
Less := [], Equal := [], More := []
Pivot := StrSplit(a[1], Delim)[index]
for k, v in a
{
x := StrSplit(v, Delim)[index]
if (x < Pivot)
less.InsertAt(1, v)
else if (x > Pivot)
more.InsertAt(1, v)
else
Equal.InsertAt(1, v)
}
Equal := OidQuickSort(Equal, Delim, index+1)
Less := OidQuickSort(Less)
Out := OidQuickSort(More)
if (Equal.Count())
Out.InsertAt(1, Equal*) ; InsertAt all values of Equal at index 1
if (Less.Count())
Out.InsertAt(1, Less*) ; InsertAt all values of Less at index 1
return Out
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">a := ["1.3.6.1.4.1.11.2.17.19.3.4.0.10"
,"1.3.6.1.4.1.11.2.17.5.2.0.79"
,"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
,"1.3.6.1.4.1.11150.3.4.0.1"
,"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
,"1.3.6.1.4.1.11150.3.4.0"]
 
for k, v in OidQuickSort(a)
Out .= "`n" v
MsgBox % Out
return</syntaxhighlight>
{{out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f SORT_A_LIST_OF_OBJECT_IDENTIFIERS.AWK
#
# sorting:
# PROCINFO["sorted_in"] is used by GAWK
# SORTTYPE is used by Thompson Automation's TAWK
#
BEGIN {
width = 10
oid_arr[++n] = "1.3.6.1.4.1.11.2.17.19.3.4.0.10"
oid_arr[++n] = "1.3.6.1.4.1.11.2.17.5.2.0.79"
oid_arr[++n] = "1.3.6.1.4.1.11.2.17.19.3.4.0.4"
oid_arr[++n] = "1.3.6.1.4.1.11150.3.4.0.1"
oid_arr[++n] = "1.3.6.1.4.1.11.2.17.19.3.4.0.1"
oid_arr[++n] = "1.3.6.1.4.1.11150.3.4.0"
# oid_arr[++n] = "1.11111111111.1" # un-comment to test error
for (i=1; i<=n; i++) {
str = ""
for (j=1; j<=split(oid_arr[i],arr2,"."); j++) {
str = sprintf("%s%*s.",str,width,arr2[j])
if ((leng = length(arr2[j])) > width) {
printf("error: increase sort key width from %d to %d for entry %s\n",width,leng,oid_arr[i])
exit(1)
}
}
arr3[str] = ""
}
PROCINFO["sorted_in"] = "@ind_str_asc" ; SORTTYPE = 1
for (i in arr3) {
str = i
gsub(/ /,"",str)
sub(/\.$/,"",str)
printf("%s\n",str)
}
exit(0)
}
</syntaxhighlight>
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|C}}==
A C99 (or later) compiler is required.
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct oid_tag {
char* str_;
int* numbers_;
int length_;
} oid;
 
// free memory, no-op if p is null
void oid_destroy(oid* p) {
if (p != 0) {
free(p->str_);
free(p->numbers_);
free(p);
}
}
 
int char_count(const char* str, char ch) {
int count = 0;
for (const char* p = str; *p; ++p) {
if (*p == ch)
++count;
}
return count;
}
 
// construct an OID from a string
// returns 0 on memory allocation failure or parse error
oid* oid_create(const char* str) {
oid* ptr = calloc(1, sizeof(oid));
if (ptr == 0)
return 0;
ptr->str_ = strdup(str);
if (ptr->str_ == 0) {
oid_destroy(ptr);
return 0;
}
int dots = char_count(str, '.');
ptr->numbers_ = malloc(sizeof(int) * (dots + 1));
if (ptr->numbers_ == 0) {
oid_destroy(ptr);
return 0;
}
ptr->length_ = dots + 1;
const char* p = str;
for (int i = 0; i <= dots && *p;) {
char* eptr = 0;
int num = strtol(p, &eptr, 10);
if (*eptr != 0 && *eptr != '.') {
// TODO: check for overflow/underflow
oid_destroy(ptr);
return 0;
}
ptr->numbers_[i++] = num;
p = eptr;
if (*p)
++p;
}
return ptr;
}
 
// compare two OIDs
int oid_compare(const void* p1, const void* p2) {
const oid* o1 = *(oid* const*)p1;
const oid* o2 = *(oid* const*)p2;
int i1 = 0, i2 = 0;
for (; i1 < o1->length_ && i2 < o2->length_; ++i1, ++i2) {
if (o1->numbers_[i1] < o2->numbers_[i2])
return -1;
if (o1->numbers_[i1] > o2->numbers_[i2])
return 1;
}
if (o1->length_ < o2->length_)
return -1;
if (o1->length_ > o2->length_)
return 1;
return 0;
}
 
int main() {
const char* input[] = {
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"
};
const int len = sizeof(input)/sizeof(input[0]);
oid* oids[len];
memset(oids, 0, sizeof(oids));
int i;
for (i = 0; i < len; ++i) {
oids[i] = oid_create(input[i]);
if (oids[i] == 0)
{
fprintf(stderr, "Out of memory\n");
goto cleanup;
}
}
qsort(oids, len, sizeof(oid*), oid_compare);
for (i = 0; i < len; ++i)
puts(oids[i]->str_);
cleanup:
for (i = 0; i < len; ++i)
oid_destroy(oids[i]);
return 0;
}</syntaxhighlight>
 
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|C sharp}}==
<syntaxhighlight lang="csharp">using System;
using System.Linq;
using System.Collections.Generic;
 
public class Program
{
public static void Main() {
var oids = new [] {
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"
};
 
var comparer = Comparer<string>.Create((a, b) => {
int c = a.Split('.').Select(int.Parse)
.Zip(b.Split('.').Select(int.Parse),
(i, j) => i.CompareTo(j)).FirstOrDefault(x => x != 0);
return c != 0 ? c : a.Length.CompareTo(b.Length);
});
 
Array.Sort(oids, comparer);
 
Console.WriteLine(string.Join(Environment.NewLine, oids));
}
}</syntaxhighlight>
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <string>
#include <vector>
#include <algorithm>
Line 79 ⟶ 1,215:
it2++ ;
}
if ( it1 == numbers1.end( ) || it2 == numbers2.end( ) )
return std::lexicographical_compare( s1.begin( ) , s1.end( ) , s2.begin( ) , s2.end( ) ) ;
return *it1 < *it2 ;
}
 
int main( ) {
std::vector<std::string> arrayOID { ".1.3.6.1.4.1.11.2.17.19.3.4.0.10" ,
".1.3.6.1.4.1.1115011.32.417.5.2.0.279" ,
".1.3.6.1.4.1.11.2.17.19.3.4.0.194" ,
".1.3.6.1.4.1.11150.3.4.0.1" ,
".1.3.6.1.4.1.11.2.17.19.3.4.0.221" ,
".1.3.6.1.4.1.11.2.17.1911150.3.4.0.2", } ;
".1.3.6.1.4.1.11150.3.4.0.11",
".1.3.6.1.4.1.11.2.17.19.3.4.0.1",
".1.3.6.1.4.1.11.2.17.3773.0.2",
".1.3.6.1.4.1.11.2.17.19.2.0.79",
".1.3.6.1.4.1.11150.3.4.0.21",
".1.3.6.1.4.1.11.2.17.19.2.0.9",
".1.3.6.1.4.1.11.2.17.19.3.4.0.25",
".1.3.6.1.4.1.11.2.17.19.3.4.0.32",
".1.3.6.1.4.1.11.2.17.19.3.4.0.4",
".1.3.6.1.4.1.11.2.17.19.3.4.0.31",
".1.3.6.1.4.1.11.2.17.19.3.4.0.3",
".1.3.6.1.4.1.11.2.17.3773.0.1" } ;
std::sort( arrayOID.begin( ) , arrayOID.end( ) , myCompare ) ;
for ( std::string s : arrayOID )
int number = 1 ;
for ( std::stringcout s<< :s arrayOID<< )'\n' {;
std::cout << "# " ;
if ( number < 10 )
std::cout << 0 << number ;
else
std::cout << number ;
std::cout << " | " << s << " |\n" ;
number++ ;
}
return 0 ;
}</langsyntaxhighlight>
{{out}}
<pre># 01 | .1.3.6.1.4.1.11.2.17.195.2.0.9 |79
# 02 | .1.3.6.1.4.1.11.2.17.19.23.4.0.79 |1
# 03 | .1.3.6.1.4.1.11.2.17.19.3.4.0.1 |4
# 04 | .1.3.6.1.4.1.11.2.17.19.3.4.0.2 |10
# 05 | .1.3.6.1.4.1.11.2.17.1911150.3.4.0.3 |
# 06 | .1.3.6.1.4.1.11.2.17.1911150.3.4.0.4 |1
# 07 | .1.3.6.1.4.1.11.2.17.19.3.4.0.10 |
# 08 | .1.3.6.1.4.1.11.2.17.19.3.4.0.19 |
# 09 | .1.3.6.1.4.1.11.2.17.19.3.4.0.22 |
# 10 | .1.3.6.1.4.1.11.2.17.19.3.4.0.25 |
# 11 | .1.3.6.1.4.1.11.2.17.19.3.4.0.31 |
# 12 | .1.3.6.1.4.1.11.2.17.19.3.4.0.32 |
# 13 | .1.3.6.1.4.1.11.2.17.3773.0.1 |
# 14 | .1.3.6.1.4.1.11.2.17.3773.0.2 |
# 15 | .1.3.6.1.4.1.11150.3.4.0.1 |
# 16 | .1.3.6.1.4.1.11150.3.4.0.2 |
# 17 | .1.3.6.1.4.1.11150.3.4.0.11 |
# 18 | .1.3.6.1.4.1.11150.3.4.0.21 |
</pre>
 
=={{header|Elixir}}==
 
=={{header|Clojure}}==
{{update|Elixir|the format description and test-case in the task description have been updated}}
Clojure 'sort' function allows specifying an optional comparator function. In this case, our custom comparator utilizes the ability of the clojure.core 'compare' function to compare vectors in an appropriate fashion.
 
<syntaxhighlight lang="clojure">
{{works with|Elixir|1.3.1}}
(defn oid-vec [oid-str]
<lang elixir>defmodule Sort_by_OID do
(->> (clojure.string/split oid-str #"\.")
(map #(Long. %))))
 
(defn oid-str [oid-vec]
(clojure.string/join "." oid-vec))
 
;;
;; If vals differ before shorter vec ends,
;; use comparison of that "common header".
;; If common part matches, compare based on num elements.
;;
(defn oid-compare [a b]
(let [min-len (min (count a) (count b))
common-cmp (compare (vec (take min-len a))
(vec (take min-len b)))]
(if (zero? common-cmp)
(compare (count a) (count b))
common-cmp)))
 
(defn sort-oids [oid-strs]
(->> (map oid-vec oid-strs)
(sort oid-compare)
(map oid-str)))
</syntaxhighlight>
 
{{out}}
<pre>
(sort-oids ["1.3.6.1.4.1.11.2.17.19.3.4.0.10"
"1.3.6.1.4.1.11.2.17.5.2.0.79"
"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
"1.3.6.1.4.1.11150.3.4.0.1"
"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
"1.3.6.1.4.1.11150.3.4.0"])
 
("1.3.6.1.4.1.11.2.17.5.2.0.79"
"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
"1.3.6.1.4.1.11.2.17.19.3.4.0.10"
"1.3.6.1.4.1.11150.3.4.0"
"1.3.6.1.4.1.11150.3.4.0.1")
</pre>
 
=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">(defun oid->list (oid)
(loop for start = 0 then (1+ pos)
for pos = (position #\. oid :start start)
collect (parse-integer oid :start start :end pos)
while pos))
 
(defun list< (list1 list2)
(loop for e1 in list1
for e2 in list2
do (cond ((< e1 e2)
(return t))
((> e1 e2)
(return nil)))
finally (return (< (length list1) (length list2)))))
 
(defun sort-oids (oids)
(sort oids #'list< :key #'oid->list))
 
(defun main ()
(let ((oids (list "1.3.6.1.4.1.11.2.17.19.3.4.0.10"
"1.3.6.1.4.1.11.2.17.5.2.0.79"
"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
"1.3.6.1.4.1.11150.3.4.0.1"
"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
"1.3.6.1.4.1.11150.3.4.0")))
(dolist (oid (sort-oids oids))
(write-line oid))))</syntaxhighlight>
{{out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">defmodule Sort_by_OID do
def numbers(list) do
Enum.sort_by(list, fn oid ->
String.split(oid, ".") |> Enum.map(&String.to_integer("0"<>&/1))
end)
end
end
 
listOID = ~w[
.1.3.6.1.4.1.11.2.17.19.3.4.0.10
.1.3.6.1.4.1.1115011.32.417.05.2.0.79
.1.3.6.1.4.1.11.2.17.19.3.4.0.194
.1.3.6.1.4.1.11150.3.4.0.1
.1.3.6.1.4.1.11.2.17.19.3.4.0.221
.1.3.6.1.4.1.11.2.17.1911150.3.4.0.2
.1.3.6.1.4.1.11150.3.4.0.11
.1.3.6.1.4.1.11.2.17.19.3.4.0.1
.1.3.6.1.4.1.11.2.17.3773.0.2
.1.3.6.1.4.1.11.2.17.19.2.0.79
.1.3.6.1.4.1.11150.3.4.0.21
.1.3.6.1.4.1.11.2.17.19.2.0.9
.1.3.6.1.4.1.11.2.17.19.3.4.0.25
.1.3.6.1.4.1.11.2.17.19.3.4.0.32
.1.3.6.1.4.1.11.2.17.19.3.4.0.4
.1.3.6.1.4.1.11.2.17.19.3.4.0.31
.1.3.6.1.4.1.11.2.17.19.3.4.0.3
.1.3.6.1.4.1.11.2.17.3773.0.1
]
|> Sort_by_OID.numbers(listOID)
|> Enum.each(fn oid -> IO.puts oid end)</syntaxhighlight>
|> Enum.with_index
|> Enum.each(fn {oid,i} ->
:io.fwrite "# ~2..0w | ~s |~n", [i+1, oid]
end)</lang>
 
{{out}}
<pre>
# 01 | .1.3.6.1.4.1.11.2.17.195.2.0.9 |79
# 02 | .1.3.6.1.4.1.11.2.17.19.23.4.0.79 |1
# 03 | .1.3.6.1.4.1.11.2.17.19.3.4.0.1 |4
# 04 | .1.3.6.1.4.1.11.2.17.19.3.4.0.2 |10
# 05 | .1.3.6.1.4.1.11.2.17.1911150.3.4.0.3 |
# 06 | .1.3.6.1.4.1.11.2.17.1911150.3.4.0.4 |1
# 07 | .1.3.6.1.4.1.11.2.17.19.3.4.0.10 |
# 08 | .1.3.6.1.4.1.11.2.17.19.3.4.0.19 |
# 09 | .1.3.6.1.4.1.11.2.17.19.3.4.0.22 |
# 10 | .1.3.6.1.4.1.11.2.17.19.3.4.0.25 |
# 11 | .1.3.6.1.4.1.11.2.17.19.3.4.0.31 |
# 12 | .1.3.6.1.4.1.11.2.17.19.3.4.0.32 |
# 13 | .1.3.6.1.4.1.11.2.17.3773.0.1 |
# 14 | .1.3.6.1.4.1.11.2.17.3773.0.2 |
# 15 | .1.3.6.1.4.1.11150.3.4.0.1 |
# 16 | .1.3.6.1.4.1.11150.3.4.0.2 |
# 17 | .1.3.6.1.4.1.11150.3.4.0.11 |
# 18 | .1.3.6.1.4.1.11150.3.4.0.21 |
</pre>
 
=={{header|HaskellFactor}}==
Factor provides the <code>human<=></code> word which converts numbers in a string to integers before comparing them.
<syntaxhighlight lang="factor">USING: io qw sequences sorting sorting.human ;
 
qw{
{{update|Haskell|the format description and test-case in the task description have been updated}}
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11150.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11150.3.4.0
} [ human<=> ] sort [ print ] each</syntaxhighlight>
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Fōrmulæ}}==
<lang Haskell>import Data.List ( sortBy , intercalate )
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Sort_a_list_of_object_identifiers}}
oid :: [String]
oid = [".1.3.6.1.4.1.11.2.17.19.3.4.0.10" ,
".1.3.6.1.4.1.11150.3.4.0.2" ,
".1.3.6.1.4.1.11.2.17.19.3.4.0.19" ,
".1.3.6.1.4.1.11150.3.4.0.1",
".1.3.6.1.4.1.11.2.17.19.3.4.0.22",
".1.3.6.1.4.1.11.2.17.19.3.4.0.2",
".1.3.6.1.4.1.11150.3.4.0.11",
".1.3.6.1.4.1.11.2.17.19.3.4.0.1",
".1.3.6.1.4.1.11.2.17.3773.0.2",
".1.3.6.1.4.1.11.2.17.19.2.0.79",
".1.3.6.1.4.1.11150.3.4.0.21",
".1.3.6.1.4.1.11.2.17.19.2.0.9",
".1.3.6.1.4.1.11.2.17.19.3.4.0.25",
".1.3.6.1.4.1.11.2.17.19.3.4.0.32",
".1.3.6.1.4.1.11.2.17.19.3.4.0.4",
".1.3.6.1.4.1.11.2.17.19.3.4.0.31",
".1.3.6.1.4.1.11.2.17.19.3.4.0.3",
".1.3.6.1.4.1.11.2.17.3773.0.1" ]
 
'''Solution'''
splitString :: Char -> String -> [String]
 
[[File:Fōrmulæ - Sort a list of object identifiers 01.png]]
 
[[File:Fōrmulæ - Sort a list of object identifiers 02.png]]
 
'''Test case'''
 
[[File:Fōrmulæ - Sort a list of object identifiers 03.png]]
 
[[File:Fōrmulæ - Sort a list of object identifiers 04.png]]
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"log"
"math/big"
"sort"
"strings"
)
 
var testCases = []string{
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0",
}
 
// a parsed representation
type oid []big.Int
 
// "constructor" parses string representation
func newOid(s string) oid {
ns := strings.Split(s, ".")
os := make(oid, len(ns))
for i, n := range ns {
if _, ok := os[i].SetString(n, 10); !ok || os[i].Sign() < 0 {
return nil
}
}
return os
}
 
// "stringer" formats into string representation
func (o oid) String() string {
s := make([]string, len(o))
for i, n := range o {
s[i] = n.String()
}
return strings.Join(s, ".")
}
 
func main() {
// parse test cases
os := make([]oid, len(testCases))
for i, s := range testCases {
os[i] = newOid(s)
if os[i] == nil {
log.Fatal("invalid OID")
}
}
// sort
sort.Slice(os, func(i, j int) bool {
// "less" function must return true if os[i] < os[j]
oi := os[i]
for x, v := range os[j] {
// lexicographic defintion: less if prefix or if element is <
if x == len(oi) || oi[x].Cmp(&v) < 0 {
return true
}
if oi[x].Cmp(&v) > 0 {
break
}
}
return false
})
// output sorted list
for _, o := range os {
fmt.Println(o)
}
}</syntaxhighlight>
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Haskell}}==
====Data.List====
<syntaxhighlight lang="haskell">import Data.List ( sort , intercalate )
 
splitString :: Eq a => (a) -> [a] -> [[a]]
splitString c [] = []
splitString c s = let ( item , rest ) = break ( == c ) s
( _ , next ) = break ( /= c ) rest
in item : splitString c next
 
convertIntListToString :: [Int] -> String
convertIntListToString list = intercalate "." $. map show list
 
orderOID :: [String] -> [String]
orderOID = map convertIntListToString . sort . map ( map read . splitString '.' )
orderOID = map (\intlist -> convertIntListToString intlist ) $ sortBy myCriterion numberlists
where
numberlists = map (\list -> map read $ tail list ) $ map (\myS -> splitString '.' myS ) oid
myCriterion :: [Int] -> [Int] -> Ordering
myCriterion a b = (\(x,y) -> compare x y ) $ head $ filter (\p -> fst p /= snd p ) $ zip a b
 
outputLineoid :: Int -> [String -> IO ( ) ]
oid = ["1.3.6.1.4.1.11.2.17.19.3.4.0.10" ,
outputLine counter s = do
"1.3.6.1.4.1.11.2.17.5.2.0.79" ,
putStr "# "
"1.3.6.1.4.1.11.2.17.19.3.4.0.4" ,
if counter < 10 then putStr ("0" ++ show counter )
"1.3.6.1.4.1.11150.3.4.0.1" ,
else putStr ( show counter )
"1.3.6.1.4.1.11.2.17.19.3.4.0.1" ,
putStr " | ."
"1.3.6.1.4.1.11150.3.4.0"]
putStr s
putStrLn " |"
 
main :: IO ( )
main = do
letmapM_ pairsputStrLn = zip$ orderOID [1..length orderOID]oid</syntaxhighlight>
mapM_ (\p -> outputLine (snd p) (fst p) ) pairs</lang>
 
{{out}}
<pre># 01 | .1.3.6.1.4.1.11.2.17.195.2.0.9 |79
# 02 | .1.3.6.1.4.1.11.2.17.19.23.4.0.79 |1
# 03 | .1.3.6.1.4.1.11.2.17.19.3.4.0.1 |4
# 04 | .1.3.6.1.4.1.11.2.17.19.3.4.0.2 |10
# 05 | .1.3.6.1.4.1.11.2.17.1911150.3.4.0.3 |
# 06 | .1.3.6.1.4.1.11.2.17.1911150.3.4.0.4 |1
# 07 | .1.3.6.1.4.1.11.2.17.19.3.4.0.10 |
# 08 | .1.3.6.1.4.1.11.2.17.19.3.4.0.19 |
# 09 | .1.3.6.1.4.1.11.2.17.19.3.4.0.22 |
# 10 | .1.3.6.1.4.1.11.2.17.19.3.4.0.25 |
# 11 | .1.3.6.1.4.1.11.2.17.19.3.4.0.31 |
# 12 | .1.3.6.1.4.1.11.2.17.19.3.4.0.32 |
# 13 | .1.3.6.1.4.1.11.2.17.3773.0.1 |
# 14 | .1.3.6.1.4.1.11.2.17.3773.0.2 |
# 15 | .1.3.6.1.4.1.11150.3.4.0.1 |
# 16 | .1.3.6.1.4.1.11150.3.4.0.2 |
# 17 | .1.3.6.1.4.1.11150.3.4.0.11 |
# 18 | .1.3.6.1.4.1.11150.3.4.0.21 |
</pre>
 
====Data.Text====
(To use '''split :: (Char -> Bool) -> Text -> [Text]''' in the standard libraries, we would have to temporarily convert the strings from [Char] to Text with pack and unpack)
 
<syntaxhighlight lang="haskell">import Data.Text (pack, split, unpack)
import Data.List (sort, intercalate)
 
-- SORTING OBJECT IDENTIFIERS ------------------------------------------------
oidSort :: [String] -> [String]
oidSort =
fmap (intercalate "." . fmap show) .
sort . fmap (fmap readInt . splitString '.')
 
-- GENERIC FUNCTIONS ---------------------------------------------------------
splitString :: Char -> String -> [String]
splitString c s = unpack <$> split (c ==) (pack s)
 
readInt :: String -> Int
readInt xs = read xs :: Int
 
-- TEST ----------------------------------------------------------------------
main :: IO ()
main =
mapM_ putStrLn $
oidSort
[ "1.3.6.1.4.1.11.2.17.19.3.4.0.10"
, "1.3.6.1.4.1.11.2.17.5.2.0.79"
, "1.3.6.1.4.1.11.2.17.19.3.4.0.4"
, "1.3.6.1.4.1.11150.3.4.0.1"
, "1.3.6.1.4.1.11.2.17.19.3.4.0.1"
, "1.3.6.1.4.1.11150.3.4.0"
]</syntaxhighlight>
{{Out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
Where Data.List.Split is available (https://hackage.haskell.org/package/split-0.2.3.1/docs/Data-List-Split.html)
we can alternatively write:
 
<syntaxhighlight lang="haskell">import Data.List.Split (splitOn)
import Data.List (sort, intercalate)
 
-- SORTING OBJECT IDENTIFIERS ------------------------------------------------
oidSort :: [String] -> [String]
oidSort =
fmap (intercalate "." . fmap show) . sort . fmap (fmap readInt . splitOn ".")
 
readInt :: String -> Int
readInt x = read x :: Int</syntaxhighlight>
 
=={{header|J}}==
Line 277 ⟶ 1,570:
Data:
 
<langsyntaxhighlight Jlang="j">oids=:<@-.&' ';._2]0 :0
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11.2.17.5.2.0.79
Line 284 ⟶ 1,577:
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11150.3.4.0
)</langsyntaxhighlight>
 
In other words, for each line in that script, remove the spaces and put the rest in a box.
Line 290 ⟶ 1,583:
Sorting:
 
<langsyntaxhighlight Jlang="j"> >(/: __&".;._1&.('.'&,)&>) oids
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
Line 296 ⟶ 1,589:
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1 </langsyntaxhighlight>
 
In other words, for our sort key, we break the contents of each box by an initial '.' and treat the remainder as numbers.
Line 302 ⟶ 1,595:
We also pull the result out of its boxes for display purposes.
 
=={{header|LuaJava}}==
{{works with|Java|8 or higher}}
 
<syntaxhighlight lang="java">
{{update|Lua|the format description and test-case in the task description have been updated}}
package com.rosettacode;
 
import java.util.Comparator;
Using the in-built table.sort with a custom compare function.
import java.util.stream.Stream;
<lang Lua>local OIDs = {
 
".1.3.6.1.4.1.11.2.17.19.3.4.0.10",
public class OIDListSorting {
".1.3.6.1.4.1.11150.3.4.0.2",
 
".1.3.6.1.4.1.11.2.17.19.3.4.0.19",
public static void main(String[] args) {
".1.3.6.1.4.1.11150.3.4.0.1",
 
".1.3.6.1.4.1.11.2.17.19.3.4.0.22",
final String dot = "\\.";
".1.3.6.1.4.1.11.2.17.19.3.4.0.2",
 
".1.3.6.1.4.1.11150.3.4.0.11",
final Comparator<String> oids_comparator = (o1, o2) -> {
".1.3.6.1.4.1.11.2.17.19.3.4.0.1",
final String[] o1Numbers = o1.split(dot), o2Numbers = o2.split(dot);
".1.3.6.1.4.1.11.2.17.3773.0.2",
for (int i = 0; ; i++) {
".1.3.6.1.4.1.11.2.17.19.2.0.79",
if (i == o1Numbers.length && i == o2Numbers.length)
".1.3.6.1.4.1.11150.3.4.0.21",
return 0;
".1.3.6.1.4.1.11.2.17.19.2.0.9",
if (i == o1Numbers.length)
".1.3.6.1.4.1.11.2.17.19.3.4.0.25",
return -1;
".1.3.6.1.4.1.11.2.17.19.3.4.0.32",
if (i == o2Numbers.length)
".1.3.6.1.4.1.11.2.17.19.3.4.0.4",
return 1;
".1.3.6.1.4.1.11.2.17.19.3.4.0.31",
final int nextO1Number = Integer.valueOf(o1Numbers[i]), nextO2Number = Integer.valueOf(o2Numbers[i]);
".1.3.6.1.4.1.11.2.17.19.3.4.0.3",
final int result = Integer.compare(nextO1Number, nextO2Number);
".1.3.6.1.4.1.11.2.17.3773.0.1"
if (result != 0)
return result;
}
};
 
Stream.of("1.3.6.1.4.1.11.2.17.19.3.4.0.10", "1.3.6.1.4.1.11.2.17.5.2.0.79", "1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1", "1.3.6.1.4.1.11.2.17.19.3.4.0.1", "1.3.6.1.4.1.11150.3.4.0")
.sorted(oids_comparator)
.forEach(System.out::println);
}
}</syntaxhighlight>
 
{{out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
=={{header|jq}}==
<syntaxhighlight lang="jq">def data: [
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"
];
 
data | map( split(".") | map(tonumber) ) | sort | map(join("."))</syntaxhighlight>
 
{{out}}
<pre>[
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11150.3.4.0",
"1.3.6.1.4.1.11150.3.4.0.1"
]</pre>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">oidlist = ["1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"]
 
sort!(oidlist; lt=lexless,
by=x -> parse.(Int, String.(split(x, "."))))
println.(oidlist)</syntaxhighlight>
 
{{out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.0.6
 
class Oid(val id: String): Comparable<Oid> {
override fun compareTo(other: Oid): Int {
val splits1 = this.id.split('.')
val splits2 = other.id.split('.')
val minSize = if (splits1.size < splits2.size) splits1.size else splits2.size
for (i in 0 until minSize) {
if (splits1[i].toInt() < splits2[i].toInt()) return -1
else if (splits1[i].toInt() > splits2[i].toInt()) return 1
}
return splits1.size.compareTo(splits2.size)
}
 
override fun toString() = id
}
 
fun main(args: Array<String>) {
val oids = arrayOf(
Oid("1.3.6.1.4.1.11.2.17.19.3.4.0.10"),
Oid("1.3.6.1.4.1.11.2.17.5.2.0.79"),
Oid("1.3.6.1.4.1.11.2.17.19.3.4.0.4"),
Oid("1.3.6.1.4.1.11150.3.4.0.1"),
Oid("1.3.6.1.4.1.11.2.17.19.3.4.0.1"),
Oid("1.3.6.1.4.1.11150.3.4.0")
)
println(oids.sorted().joinToString("\n"))
}</syntaxhighlight>
 
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Lua}}==
Using the in-built table.sort with a custom compare function.
<syntaxhighlight lang="lua">local OIDs = {
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"
}
function compare (a, b)
local aList, bList, Na, Nb = {}, {}
Line 333 ⟶ 1,741:
for num in b:gmatch("%d+") do table.insert(bList, num) end
for i = 1, math.max(#aList, #bList) do
Na, Nb = tonumber(aList[i]) or 0, tonumber(bList[i]) or 0
if Na ~= Nb then return Na < Nb end
end
end
 
table.sort(OIDs, compare)
table.foreachfor _, oid in pairs(OIDs,) do print(oid) end</langsyntaxhighlight>
{{out}}
<pre>1 .1.3.6.1.4.1.11.2.17.195.2.0.979
2 .1.3.6.1.4.1.11.2.17.19.23.4.0.791
3 .1.3.6.1.4.1.11.2.17.19.3.4.0.14
4 .1.3.6.1.4.1.11.2.17.19.3.4.0.210
5 .1.3.6.1.4.1.11.2.17.1911150.3.4.0.3
6 .1.3.6.1.4.1.11.2.17.1911150.3.4.0.41</pre>
===Using Coroutine===
7 .1.3.6.1.4.1.11.2.17.19.3.4.0.10
<syntaxhighlight lang="lua">
8 .1.3.6.1.4.1.11.2.17.19.3.4.0.19
local function oidGen(s)
9 .1.3.6.1.4.1.11.2.17.19.3.4.0.22
local wrap, yield = coroutine.wrap, coroutine.yield
10 .1.3.6.1.4.1.11.2.17.19.3.4.0.25
return wrap(function()
11 .1.3.6.1.4.1.11.2.17.19.3.4.0.31
for n in s:gmatch"%d+"do yield(tonumber(n))end
12 .1.3.6.1.4.1.11.2.17.19.3.4.0.32
end)
13 .1.3.6.1.4.1.11.2.17.3773.0.1
end
14 .1.3.6.1.4.1.11.2.17.3773.0.2
 
15 .1.3.6.1.4.1.11150.3.4.0.1
local function oidCmp(a,b)
16 .1.3.6.1.4.1.11150.3.4.0.2
local agen,bgen = oidGen(a),oidGen(b)
17 .1.3.6.1.4.1.11150.3.4.0.11
local n,m = agen(),bgen()
18 .1.3.6.1.4.1.11150.3.4.0.21</pre>
while n and m do
if n~=m then return n<m end
n,m = agen(),bgen()
end
return m and true or false -- bgen longer with previous equal
end
 
local OIDs = {
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"
}
table.sort(OIDs, oidCmp)
for _, oid in pairs(OIDs) do print(oid) end
</syntaxhighlight>
 
=={{header|M2000 Interpreter}}==
In this example we have to change dot to #, to make each number as an integer one.
<syntaxhighlight lang="m2000 interpreter">
Module CheckIt {
Flush ' empty stack of values
Data "1.3.6.1.4.1.11.2.17.19.3.4.0.4" , "1.3.6.1.4.1.11.2.17.19.3.4.0.1", "1.3.6.1.4.1.11150.3.4.0.1"
Data "1.3.6.1.4.1.11.2.17.19.3.4.0.10", "1.3.6.1.4.1.11.2.17.5.2.0.79", "1.3.6.1.4.1.11150.3.4.0"
\\ Inventories of type queue can get same keys, and have sort where numbers (float type) as part of key count as numbers
Inventory queue OID
\\ prepare keys (replace dot to #)
While not empty {
Append OID, Replace$(".","#", letter$)
}
Sort Ascending OID
n=Each(OID)
a$=""
While n {
\\ replace # to dot
a$+=Replace$("#",".", Eval$(n))+{
}
}
Clipboard a$
Report a$
}
Checkit
</syntaxhighlight>
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
===Using Piece$() and Stack Sort===
We use a stack (a linked list) to save numbers, and a function to check piece by piece for "Grater than" only
 
piece$(a$,".")(i) works from 0
 
piece$(a$,".", i) works from 1
 
piece$(a$,".") export a pointer to an array with each piece on it
 
 
<syntaxhighlight lang="m2000 interpreter">
GT=lambda (a$, b$)->{
def i
do {
m$=piece$(a$,".")(i)
n$=piece$(b$,".")(i)
i++
} until n$="" or m$="" or m$<>n$
if n$="" then =m$<>"":exit
if m$="" then =False:exit
=val(m$)>val(n$)
}
Stack new {
\\ data push to end of stack (we use it as FIFO)
data "1.3.6.1.4.1.11.2.17.19.3.4.0.10"
data "1.3.6.1.4.1.11.2.17.5.2.0.79"
data "1.3.6.1.4.1.11.2.17.19.3.4.0.4"
data "1.3.6.1.4.1.11150.3.4.0.1"
data "1.3.6.1.4.1.11.2.17.19.3.4.0.1"
data "1.3.6.1.4.1.11150.3.4.0"
M=Stack.Size-1
While M>0 {
N=1
For i=1 to M {
\\ if peek item i > peek item i+1 then get i+1 to top, and send to i
\\ stack is a linked list, so moving items done with pointers only
if Gt(stackitem$(i), stackitem$(i+1)) then Shift i+1 : ShiftBack i : N=i
}
M=N-1
}
While not empty {
Print Letter$
}
}
</syntaxhighlight>
 
Using a function which split pieces one time. We have to insert one more item, by append a "." to a$ and b$
<syntaxhighlight lang="m2000 interpreter">
GT=lambda (a$, b$)->{
def i=-1
dim Base 0, a$(), b$()
a$()=piece$(a$+".", ".")
b$()=piece$(b$+".", ".")
do {
i++
} until a$(i)="" or b$(i)="" or a$(i)<>b$(i)
if b$(i)="" then =a$(i)<>"":exit
if a$(i)="" then =False:exit
=val(a$(i))>val(b$(i))
}
</syntaxhighlight>
 
===Using QuickSort===
We can make any OID as array of numbers and we can put all OIDs in an array to sort by a custom Quick Sort, where we place the compare function as a lambda function. Swaps made to pointers of arrays of OIDs. There is no need to use PIECE$() in compare function.
 
Note that QuickSort need Lower or Equal
 
There is a Let numeric_expression = string_expression
Normally this numeric_expression = string_expression is a syntax error,
but Let is a two part statement, a Push to stack and a Read from stack: Push string_expression : Read numeric_expression
So first executed the string expression which return a pointer to array and then the read statement get this pointer;
 
 
<syntaxhighlight lang="m2000 interpreter">
Group Quick {
Private:
Function partition {
Read &A(), p, r
x = A(r)
i = p-1
For j=p to r-1 {
If .LE(A(j), x) Then {
i++
Swap A(i),A(j)
}
}
Swap A(i+1),A(r)
= i+1
}
Public:
LE=Lambda->False
Function quicksort {
Read &A(), p, r
If p < r Then {
q = .partition(&A(), p, r)
Call .quicksort(&A(), p, q - 1)
Call .quicksort(&A(), q + 1, r)
}
}
}
\\ no easy way to join ;
\\ n^ is the cursor from iterator n
Function join$(a$()) {
n=each(a$(), 1, -2)
k$=""
while n {
overwrite k$, ".", n^:=array$(n)
}
=k$
}
Stack New {
Data "1.3.6.1.4.1.11.2.17.19.3.4.0.4" , "1.3.6.1.4.1.11.2.17.19.3.4.0.1", "1.3.6.1.4.1.11150.3.4.0.1"
Data "1.3.6.1.4.1.11.2.17.19.3.4.0.10", "1.3.6.1.4.1.11.2.17.5.2.0.79", "1.3.6.1.4.1.11150.3.4.0"
Dim Base 0, arr(Stack.Size)
link arr() to arr$()
i=0 : While not Empty {arr$(i)=piece$(letter$+".", ".") : i++ }
}
Print "Unsorted"
For i=0 to len(arr())-1 {
Print join$(arr(i))
}
Quick.LE=lambda (a, b)->{
Link a, b to a$(), b$()
def i=-1
do {
i++
} until a$(i)="" or b$(i)="" or a$(i)<>b$(i)
if b$(i)="" then =a$(i)="":exit
if a$(i)="" then =true:exit
=val(a$(i))<=val(b$(i))
}
Call Quick.quicksort(&arr(), 0, Len(arr())-1)
Print "Sorted"
For i=0 to len(arr())-1 {
Print join$(arr(i))
}
</syntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">in = {"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79", "1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1", "1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"};
in = StringSplit[#, "."] & /@ in;
in = Map[ToExpression, in, {2}];
Column[StringRiffle[ToString /@ #, "."] & /@ LexicographicSort[in]]</syntaxhighlight>
{{out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
=={{header|Nim}}==
=== OID as distinct string ===
Nim allows to define distinct types. As OID are peculiar strings, defining them as distinct strings seems a good idea. We have to define a specific comparison procedure and that’s all. Here is the code:
<syntaxhighlight lang="nim">import algorithm, sequtils, strutils
 
type OID = distinct string
 
# Borrow the `$` procedure from the base string type.
proc `$`(oid: OID): string {.borrow.}
 
 
template toSeqInt(oid: OID): seq[int] =
## Convert an OID into a sequence of integers.
oid.string.split('.').map(parseInt)
 
 
proc oidCmp(a, b: OID): int =
## Compare two OIDs. Return 0 if OIDs are equal, -1 if the first is
## less than the second, +1 is the first is greater than the second.
let aseq = a.toSeqInt
let bseq = b.toSeqInt
for i in 0..<min(aseq.len, bseq.len):
result = cmp(aseq[i], bseq[i])
if result != 0: return
result = cmp(aseq.len, bseq.len)
 
 
when isMainModule:
 
const OIDS = [OID"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
OID"1.3.6.1.4.1.11.2.17.5.2.0.79",
OID"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
OID"1.3.6.1.4.1.11150.3.4.0.1",
OID"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
OID"1.3.6.1.4.1.11150.3.4.0"]
 
for oid in OIDS.sorted(oidCmp):
echo oid</syntaxhighlight>
 
Note that as the type is distinct, we have to borrow the procedure `$` to the string type in order to print OID values.
 
{{out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
=== OID as composite object ===
 
The previous method is elegant but not very efficient. Indeed, every time a comparison is done, two conversions to a sequence of integers are done. And when sorting an array of OIDs, the same conversion is done several time.
 
To avoid this, we can define OID as a composite object type containing a string value and a list of integers to use for the comparisons. The code is not really more complicated, only arguably less elegant as we have to create the OIDs using the procedure “initOID”.
 
<syntaxhighlight lang="nim">import algorithm, sequtils, strutils
 
type OID = object
value: string
list: seq[int]
 
proc initOID(s: string): OID =
OID(value: s, list: s.split('.').map(parseInt))
 
proc `$`(oid: OID): string =
oid.value
 
proc oidCmp(a, b: OID): int =
## Compare two OIDs. Return 0 if OIDs are equal, -1 if the first is
## less than the second, +1 is the first is greater than the second.
for i in 0..<min(a.list.len, b.list.len):
result = cmp(a.list[i], b.list[i])
if result != 0: return
result = cmp(a.list.len, b.list.len)
 
 
when isMainModule:
 
const OIDS = [initOID("1.3.6.1.4.1.11.2.17.19.3.4.0.10"),
initOID("1.3.6.1.4.1.11.2.17.5.2.0.79"),
initOID("1.3.6.1.4.1.11.2.17.19.3.4.0.4"),
initOID("1.3.6.1.4.1.11150.3.4.0.1"),
initOID("1.3.6.1.4.1.11.2.17.19.3.4.0.1"),
initOID("1.3.6.1.4.1.11150.3.4.0")]
 
for oid in OIDS.sorted(oidCmp):
echo oid</syntaxhighlight>
 
{{out}}
Same as with the previous method.
 
=={{header|Perl}}==
 
<langsyntaxhighlight lang="perl">my @OIDs = qw(
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11.2.17.5.2.0.79
Line 377 ⟶ 2,084:
@OIDs;
 
print "$_\n" for @sorted;</langsyntaxhighlight>
 
{{out}}
Line 389 ⟶ 2,096:
</pre>
 
Alternately, you can sort them as "version strings", which is a Perl syntax allowing you to specify a character string in the source code with the characters' codes specified as a dot-delimited sequence of integers.
=={{header|Perl 6}}==
 
<syntaxhighlight lang="perl">my @sorted =
map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [$_, eval "v$_"] }
@OIDs;</syntaxhighlight>
 
=={{header|Phix}}==
{{libheader|Phix/basics}}
This is a variation on a standard tagsort, but performed a bit more explicitly.
<!--<syntaxhighlight lang="phix">-->
<span style="color: #004080;">sequence</span> <span style="color: #000000;">strings</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"1.3.6.1.4.1.11.2.17.19.3.4.0.10"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11.2.17.5.2.0.79"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11.2.17.19.3.4.0.4"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11150.3.4.0.1"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11.2.17.19.3.4.0.1"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11150.3.4.0"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sortable</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">si</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">to_number</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">sortable</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">si</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">sortable</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sortable</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sortable</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
"1.3.6.1.4.1.11.2.17.5.2.0.79"
"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
"1.3.6.1.4.1.11.2.17.19.3.4.0.10"
"1.3.6.1.4.1.11150.3.4.0"
"1.3.6.1.4.1.11150.3.4.0.1"
</pre>
 
===alternative===
This is very similar to the above, but without using any tags/indexes at all.
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">constant</span> <span style="color: #000000;">strings</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"1.3.6.1.4.1.11.2.17.19.3.4.0.10"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11.2.17.5.2.0.79"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11.2.17.19.3.4.0.4"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11150.3.4.0.1"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11.2.17.19.3.4.0.1"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.3.6.1.4.1.11150.3.4.0"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">each</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">original</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sortable</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">original</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">to_number</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">sortable</span><span style="color: #0000FF;">,</span><span style="color: #000000;">original</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000080;font-style:italic;">-- sort on sortable, then use vslice to extract the originals:</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">vslice</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">,</span><span style="color: #000000;">each</span><span style="color: #0000FF;">)),</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Phixmonti}}==
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt
 
( "1.3.6.1.4.1.11.2.17.19.3.4.0.10"
"1.3.6.1.4.1.11.2.17.5.2.0.79"
"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
"1.3.6.1.4.1.11150.3.4.0.1"
"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
"1.3.6.1.4.1.11150.3.4.0" )
 
len for
var i
i get "." " " subst split
len for
var j
j get tonum j set
endfor
i set
endfor
 
sort
 
len for
var i
i get
"" var string
len for
get tostr "." chain string swap chain var string
endfor
drop
string 0 del i set
endfor
 
len for get print nl endfor
</syntaxhighlight>
 
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">(for I
(by
'((L) (mapcar format (split (chop L) ".")))
sort
(quote
"1.3.6.1.4.1.11.2.17.19.3.4.0.10"
"1.3.6.1.4.1.11.2.17.5.2.0.79"
"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
"1.3.6.1.4.1.11150.3.4.0.1"
"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
"1.3.6.1.4.1.11150.3.4.0" ) )
(prinl I) )</syntaxhighlight>
{{out}}
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
=={{header|Prolog}}==
{{works with|SWI Prolog}}
<syntaxhighlight lang="prolog">main:-
sort_oid_list(["1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"], Sorted_list),
foreach(member(oid(_, Oid), Sorted_list), writeln(Oid)).
 
sort_oid_list(Oid_list, Sorted_list):-
parse_oid_list(Oid_list, Parsed),
sort(1, @=<, Parsed, Sorted_list).
 
parse_oid_list([], []):-!.
parse_oid_list([Oid|Oid_list], [oid(Numbers, Oid)|Parsed]):-
parse_oid(Oid, Numbers),
parse_oid_list(Oid_list, Parsed).
 
parse_oid(Oid, Numbers):-
split_string(Oid, ".", ".", Strings),
number_strings(Numbers, Strings).
 
number_strings([], []):-!.
number_strings([Number|Numbers], [String|Strings]):-
number_string(Number, String),
number_strings(Numbers, Strings).</syntaxhighlight>
 
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Python}}==
 
We need to split the input and map each part to int otherwise elements gets compared as a string
<syntaxhighlight lang="python">
data = [
'1.3.6.1.4.1.11.2.17.19.3.4.0.10',
'1.3.6.1.4.1.11.2.17.5.2.0.79',
'1.3.6.1.4.1.11.2.17.19.3.4.0.4',
'1.3.6.1.4.1.11150.3.4.0.1',
'1.3.6.1.4.1.11.2.17.19.3.4.0.1',
'1.3.6.1.4.1.11150.3.4.0'
]
 
for s in sorted(data, key=lambda x: list(map(int, x.split('.')))):
print(s)
</syntaxhighlight>
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">#lang racket
(require data/order)
 
;; allows for key caching
(define (oid->oid-key o)
(map string->number (string-split o ".")))
 
(define oid-key< (order-<? datum-order))
 
(module+ test
(require rackunit)
(check-equal?
(sort
'("1.3.6.1.4.1.11.2.17.19.3.4.0.10"
"1.3.6.1.4.1.11.2.17.5.2.0.79"
"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
"1.3.6.1.4.1.11150.3.4.0.1"
"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
"1.3.6.1.4.1.11150.3.4.0")
oid-key<
#:key oid->oid-key
#:cache-keys? #t)
'("1.3.6.1.4.1.11.2.17.5.2.0.79"
"1.3.6.1.4.1.11.2.17.19.3.4.0.1"
"1.3.6.1.4.1.11.2.17.19.3.4.0.4"
"1.3.6.1.4.1.11.2.17.19.3.4.0.10"
"1.3.6.1.4.1.11150.3.4.0"
"1.3.6.1.4.1.11150.3.4.0.1")))</syntaxhighlight>
Tests run with no output, indicating success.
 
=={{header|Raku}}==
(formerly Perl 6)
 
The <tt>sort</tt> routine accepts a sort key callback as the first argument. Here we generate a list of integers as the sort key for each OID, which gets sorted lexicographically with numeric comparison by default.
 
<syntaxhighlight lang="raku" perl6line>.say for sort *.comb(/\d+/)».Int, <
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11.2.17.5.2.0.79
Line 400 ⟶ 2,323:
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11150.3.4.0
>;</langsyntaxhighlight>
 
{{out}}
Line 414 ⟶ 2,337:
Alternatively, using the <tt>sprintf</tt>-based approach used by the Perl solution, for comparison ''(input elided)'':
 
<syntaxhighlight lang="raku" perl6line>.say for sort *.split('.').fmt('%08d'), <...>;</langsyntaxhighlight>
 
Or if using a third-party module is acceptable:
 
<syntaxhighlight lang="raku" Perl6line>use Sort::Naturally;
 
.say for sort &naturally, <...>;</langsyntaxhighlight>
 
=={{header|REXX}}==
This REXX version supports thenegative newintegers andin oldthe formatOID. &nbsp; (supports a leading decimal point).
<langsyntaxhighlight lang="rexx">/*REXX program performs a sort of OID (Object IDentifiers ◄── used in Network data). */
call gen /*generate an array (@.) from the OIDs.*/
$= 1.3.6.1.4.1.11.2.17.19.3.4.0.10 ,
1.3.6.1.4.1.11.2.17.5.2.0.79 ,
1.3.6.1.4.1.11.2.17.19.3.4.0.4 ,
1.3.6.1.4.1.11150.3.4.0.1 ,
1.3.6.1.4.1.11.2.17.19.3.4.0.1 ,
1.3.6.1.4.1.11150.3.4.0
#=words($) /*#: the number of OIDs in the $ list.*/
a=; do i=1 for #; @.i=word($, i); a=a @.i /*build the @ array; build a composite.*/
end /*i*/ /*A will be a list of all internal #s.*/
 
a=translate(a, , .); n=words(a) /*remove all the decimal points in A. */
w=0 /*W: the widest decimal number in A. */
do m=1 for n; w=max(w, length(word(a,m))) /*find width of widest num. in all OIDs*/
end /*m*/
 
call show 'before sort ───► ' /*display the @ array before sorting.*/
say copies('▒', 75) say copies('░', 79) /*display a " fence, sep theseparate before & after*/
call normaadj 1 /*expand all the internal $ list of OID numbers. */
call bSort # /*invokesort bubble sort to sort numbers." " " " " " */
call normaadj 0 /*shrink all the internal" " " " " " OID numbers. */
call show ' after sort ───► ' /*display the @ array after sorting. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
bSort: procedure expose @.; parse arg n; m=n-1 /*N: is the number of @ array elements. */
do m=m for m by -1 until ok; ok= 1 /*keep sorting the @ array until done. */
do j=1 for m; k _= j + 1; if @.j<=@.k then iterate /*Notcalculate the next (index) in @ out─of─order?array*/
if _=@.j;>@._ then parse value @.j=@.k; @.k=_; 0 ok=0 /*swap twowith elements; flag as not done@.*/_ @.j ok
end /*j*/ /* [↑] swap two out─of─order elements.*/
end /*m*/; return /* [↑] use a simple bubble sort. */
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
gen: $= 1.3.6.1.4.1.11.2.17.19.3.4.0.10 , /* ◄──┐ */
norma: parse arg LZ; do j=1 for #; x=@.j; y=left(., left(x, 1)==.)
1.3.6.1.4.1.11.2.17.5.2.0.79 , /* ◄──┤ if y==. then x=substr(x,2) /*X have leading dot?*/
1.3.6.1.4.1.11.2.17.19.3.4.0.4 , /* ◄──┼─◄─ six OID numbers (as a list).*/
do while x\==''; parse var x z "." x /*extract number.*/
1.3.6.1.4.1.11150.3.4.0.1 , /* ◄──┤ if LZ then y=y || right(z, w, 0). /*added leading 0's ?*/
1.3.6.1.4.1.11.2.17.19.3.4.0.1 , /* ◄──┤ else y=y || z+0 || . /*elide " " */
1.3.6.1.4.1.11150.3.4.0 /* ◄──┘ end /*while*/
w= 0 @.j=strip(y, 'T', .) /*useW: newmax length Yof version#'s.*/
#= words($); do i=1 for #; @.i= word($, endi); w= max(w, /*length(@.i*/) /*LZ: Leading Zero(es)*/
return end /*i*/ /*── ─ ─ W: max length of #'s.*/
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
showadj: arg LZ; do sj=1 for #; say " x= OID number" righttranslate(s@.j, length(#)), arg(1) @.s); end; y= /*construct X version. return<*/lang>
do k=1 for words(x); _= word(x, k) /*get a number in X. */
'''output''' &nbsp; when using the (internal) default numbers:
if LZ then y= y right(_, w, 0) /*(prepend) leading 0's*/
else y= y (_ + 0) /* (elide) " " */
end /*k*/
@.j = translate( space(y), ., ' ') /*reconstitute number. */
end /*j*/ /*LZ: Leading Zero(s).*/
return /*── ─ ─ */
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: do a=1 for #; say right("OID number",20) right(a,length(#)) arg(1) @.a; end; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the (internal) default input:}}
<pre>
OID number 1 before sort ───► 1.3.6.1.4.1.11.2.17.19.3.4.0.10
OID number 2 before sort ───► 1.3.6.1.4.1.11.2.17.5.2.0.79
OID number 3 before sort ───► 1.3.6.1.4.1.11.2.17.19.3.4.0.4
OID number 4 before sort ───► 1.3.6.1.4.1.11150.3.4.0.1
OID number 5 before sort ───► 1.3.6.1.4.1.11.2.17.19.3.4.0.1
OID number 6 before sort ───► 1.3.6.1.4.1.11150.3.4.0
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
OID number 1 after sort ───► 1.3.6.1.4.1.11.2.17.5.2.0.79
OID number 2 after sort ───► 1.3.6.1.4.1.11.2.17.19.3.4.0.1
OID number 3 after sort ───► 1.3.6.1.4.1.11.2.17.19.3.4.0.4
OID number 4 after sort ───► 1.3.6.1.4.1.11.2.17.19.3.4.0.10
OID number 5 after sort ───► 1.3.6.1.4.1.11150.3.4.0
OID number 6 after sort ───► 1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Ring}}==
 
<syntaxhighlight lang="ring">
{{update|Ring|the format description and test-case in the task description have been updated}}
 
<lang Ring>
 
/*
Line 500 ⟶ 2,418:
oldOidList =
[
".1.3.6.1.4.1.1115011.2.17.19.3.4.0.2110",
".1.3.6.1.4.1.1115011.32.417.5.2.0.1179",
".1.3.6.1.4.1.1115011.2.17.19.3.4.0.24",
".1.3.6.1.4.1.11150.3.4.0.1",
".1.3.6.1.4.1.11.2.17.377319.3.4.0.21",
".1.3.6.1.4.1.1111150.23.17.37734.0.1",
]
".1.3.6.1.4.1.11.2.17.19.3.4.0.32",
".1.3.6.1.4.1.11.2.17.19.3.4.0.31",
".1.3.6.1.4.1.11.2.17.19.3.4.0.25",
".1.3.6.1.4.1.11.2.17.19.3.4.0.22",
".1.3.6.1.4.1.11.2.17.19.3.4.0.19",
".1.3.6.1.4.1.11.2.17.19.3.4.0.10",
".1.3.6.1.4.1.11.2.17.19.3.4.0.4" ,
".1.3.6.1.4.1.11.2.17.19.3.4.0.3" ,
".1.3.6.1.4.1.11.2.17.19.3.4.0.2" ,
".1.3.6.1.4.1.11.2.17.19.3.4.0.1" ,
".1.3.6.1.4.1.11.2.17.19.2.0.79",
".1.3.6.1.4.1.11.2.17.19.2.0.9"
]
 
### SHOW BEFORE SORT
Line 608 ⟶ 2,514:
###-----------------------------------------------------------
 
>;</langsyntaxhighlight>
{{out}}
<pre>
 
newOIDList Final Sort
.1.3.6.1.4.1.11.2.17.19.2.0.9
.1.3.6.1.4.1.11.2.17.195.2.0.79
.1.3.6.1.4.1.11.2.17.19.3.4.0.1
.1.3.6.1.4.1.11.2.17.19.3.4.0.2
.1.3.6.1.4.1.11.2.17.19.3.4.0.3
.1.3.6.1.4.1.11.2.17.19.3.4.0.4
.1.3.6.1.4.1.11.2.17.19.3.4.0.10
.1.3.6.1.4.1.11.2.17.1911150.3.4.0.19
.1.3.6.1.4.1.11.2.17.19.3.4.0.22
.1.3.6.1.4.1.11.2.17.19.3.4.0.25
.1.3.6.1.4.1.11.2.17.19.3.4.0.31
.1.3.6.1.4.1.11.2.17.19.3.4.0.32
.1.3.6.1.4.1.11.2.17.3773.0.1
.1.3.6.1.4.1.11.2.17.3773.0.2
.1.3.6.1.4.1.11150.3.4.0.1
.1.3.6.1.4.1.11150.3.4.0.2
.1.3.6.1.4.1.11150.3.4.0.11
.1.3.6.1.4.1.11150.3.4.0.21
 
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">%w[
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11150.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11150.3.4.0
]
.sort_by{|oid| oid.split(".").map(&:to_i)}
.each{|oid| puts oid}</syntaxhighlight>
 
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
Or, using the Gem module (which knows about versions):
<syntaxhighlight lang="ruby">puts %w[
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11150.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11150.3.4.0
].sort_by{|oid| Gem::Version.new(oid) }</syntaxhighlight>
with identical output.
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn split(s: &str) -> impl Iterator<Item = u64> + '_ {
s.split('.').map(|x| x.parse().unwrap())
}
 
fn main() {
let mut oids = vec![
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0",
];
 
oids.sort_by(|a, b| Iterator::cmp(split(a), split(b)));
println!("{:#?}", oids);
}</syntaxhighlight>
{{out}}
<pre>[
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11150.3.4.0",
"1.3.6.1.4.1.11150.3.4.0.1"
]</pre>
 
=={{header|Sather}}==
<syntaxhighlight lang="sather">class MAIN is
oid_lt (a, b: STR): BOOL is
as ::= a.cursor.split('.');
bs ::= b.cursor.split('.');
loop
na ::= #INT(as.elt!);
nb ::= #INT(bs.elt!);
if na /= nb then return na < nb; end;
end;
return as.size < bs.size;
end;
 
main is
sorter: ARR_SORT_ALG{STR, ARRAY{STR}};
input: ARRAY{STR} := |"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"|;
sorted ::= input.copy;
sorter.sort_by(sorted, bind(oid_lt(_, _)));
 
#OUT+"unsorted:\n";
loop #OUT+input.elt! + "\n"; end;
 
#OUT+"sorted:\n";
loop #OUT+sorted.elt! + "\n"; end;
end;
end;</syntaxhighlight>
{{out}}
<pre>
unsorted:
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11150.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11150.3.4.0
sorted:
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func sort_OIDs(ids) {
ids.sort_by { |id|
id.split('.').map { Num(_) }
Line 649 ⟶ 2,654:
)
 
sort_OIDs(OIDs).each { .say }</langsyntaxhighlight>
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">import Foundation
 
public struct OID {
public var val: String
 
public init(_ val: String) {
self.val = val
}
}
 
extension OID: CustomStringConvertible {
public var description: String {
return val
}
}
 
extension OID: Comparable {
public static func < (lhs: OID, rhs: OID) -> Bool {
let split1 = lhs.val.components(separatedBy: ".").compactMap(Int.init)
let split2 = rhs.val.components(separatedBy: ".").compactMap(Int.init)
let minSize = min(split1.count, split2.count)
 
for i in 0..<minSize {
if split1[i] < split2[i] {
return true
} else if split1[i] > split2[i] {
return false
}
}
 
return split1.count < split2.count
}
 
public static func == (lhs: OID, rhs: OID) -> Bool {
return lhs.val == rhs.val
}
}
 
let ids = [
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"
].map(OID.init)
 
for id in ids.sorted() {
print(id)
}</syntaxhighlight>
 
{{out}}
 
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1</pre>
 
=={{header|Tcl}}==
<syntaxhighlight lang="tcl">
# Example input data:
set oid_list [list \
1.3.6.1.4.1.11.2.17.19.3.4.0.10 \
1.3.6.1.4.1.11.2.17.5.2.0.79 \
1.3.6.1.4.1.11.2.17.19.3.4.0.4 \
1.3.6.1.4.1.11150.3.4.0.1 \
1.3.6.1.4.1.11.2.17.19.3.4.0.1 \
1.3.6.1.4.1.11150.3.4.0 ]
set oid2_lists [list ]
set dots_max 0
set i 0
foreach oid $oid_list {
set oid_list [split $oid "."]
set dot_count [llength $oid_list]
incr dot_count -1
if { $dot_count > $dots_max } {
set dots_max $dot_count
}
set dots_arr(${i}) $dot_count
lappend oid2_lists $oid_list
incr i
}
# pad for strings of different dot counts
set oid3_lists [list]
for {set ii 0} {$ii < $i} {incr ii} {
set oid_list [lindex $oid2_lists $ii]
set add_fields [expr { $dots_max - $dots_arr(${ii}) } ]
if { $add_fields > 0 } {
for {set j 0} {$j < $add_fields} {incr j} {
lappend oid_list -1
}
}
lappend oid3_lists $oid_list
}
for {set n $dots_max} {$n >= 0 } {incr n -1} {
set oid3_lists [lsort -integer -index $n -increasing $oid3_lists]
}
# unpad strings of different dot counts
set oid4_lists [list]
for {set ii 0} {$ii < $i} {incr ii} {
set oid_list [lindex $oid3_lists $ii]
set j [lsearch -exact -integer $oid_list -1]
if { $j > -1 } {
set oid2_list [lrange $oid_list 0 ${j}-1]
lappend oid4_lists $oid2_list
} else {
lappend oid4_lists $oid_list
}
}
foreach oid_list $oid4_lists {
puts [join $oid_list "."]
}
</syntaxhighlight>
 
{{out}}
<pre>
% source sort-a-list-of-oids.tcl
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">' Sort a list of object identifiers - VBScript
function myCompare(x,y)
dim i,b
sx=split(x,".")
sy=split(y,".")
b=false
for i=0 to ubound(sx)
if i > ubound(sy) then b=true: exit for
select case sgn(int(sx(i))-int(sy(i)))
case 1: b=true: exit for
case -1: b=false: exit for
end select
next
myCompare=b
end function
 
function bubbleSort(t)
dim i,n
n=ubound(t)
do
changed=false
n= n-1
for i=0 to n
if myCompare(t(i),t(i+1)) then
tmp=t(i): t(i)=t(i+1): t(i+1)=tmp
changed=true
end if
next
loop until not changed
bubbleSort=t
end function
a=array( _
"1.3.6.1.4.1.11.2.17.19.3.4.0.10", _
"1.3.6.1.4.1.11.2.17.5.2.0.79", _
"1.3.6.1.4.1.11.2.17.19.3.4.0.4", _
"1.3.6.1.4.1.11150.3.4.0.1", _
"1.3.6.1.4.1.11.2.17.19.3.4.0.1", _
"1.3.6.1.4.1.11150.3.4.0")
bubbleSort a
wscript.echo join(a,vbCrlf) </syntaxhighlight>
{{out}}
<pre>
1.3.6.1.4.1.11.2.17.5.2.0.79
1.3.6.1.4.1.11.2.17.19.3.4.0.1
1.3.6.1.4.1.11.2.17.19.3.4.0.4
1.3.6.1.4.1.11.2.17.19.3.4.0.10
1.3.6.1.4.1.11150.3.4.0
1.3.6.1.4.1.11150.3.4.0.1
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
{{libheader|Wren-sort}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
import "./sort" for Sort
 
var oids = [
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
"1.3.6.1.4.1.11150.3.4.0.1",
"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
"1.3.6.1.4.1.11150.3.4.0"
]
 
oids = oids.map { |oid| Fmt.v("s", 5, oid.split("."), 0, ".", "") }.toList
Sort.quick(oids)
oids = oids.map { |oid| oid.replace(" ", "") }.toList
System.print(oids.join("\n"))</syntaxhighlight>
 
{{out}}
<pre>
Line 664 ⟶ 2,880:
 
Basically, blow apart each line into a list of numbers and sort that.
<langsyntaxhighlight lang="zkl">fcn sortOIDS(oids){ // oids is not modified, a new list is created
// pad each oid with a terminal (-1) so zip won't short cut
oids=oids.pump(List(),fcn(oid){ (oid + ".-1").split(".").apply("toInt") });
Line 675 ⟶ 2,891:
});
oids.pump(List,fcn(list){ list[0,-1].concat(".") }) // back to strings
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">oids:=List(
"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
"1.3.6.1.4.1.11.2.17.5.2.0.79",
Line 684 ⟶ 2,900:
"1.3.6.1.4.1.11150.3.4.0");
oids=sortOIDS(oids);
oids.pump(Console.println); // print one OID per line</langsyntaxhighlight>
{{out}}
<pre>
9,483

edits