Sort a list of object identifiers: Difference between revisions
(Task description: Improve formatting, wording, and be explicit about the specification) |
(task description: make the test-case shorter, more useful (catches edge-cases), and accurate (Wikipedia article says nothing about a leading dot)) |
||
Line 9: | Line 9: | ||
{{task heading|Details}} |
{{task heading|Details}} |
||
* An OID consists of one or more non-negative integers in base 10, separated by dots. |
* 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:Lexicographical|lexicographical]] with regard to the dot-separated fields, using numeric comparison between fields. |
* Their natural sort order is [[wp:Lexicographical|lexicographical]] with regard to the dot-separated fields, using numeric comparison between fields. |
||
Line 20: | Line 20: | ||
|- |
|- |
||
| |
| |
||
<code> |
<code>1.3.6.1.4.1.11.2.17.19.3.4.0.10</code><br> |
||
<code> |
<code>1.3.6.1.4.1.11.2.17.5.2.0.79</code><br> |
||
<code> |
<code>1.3.6.1.4.1.11.2.17.19.3.4.0.4</code><br> |
||
<code> |
<code>1.3.6.1.4.1.11150.3.4.0.1</code><br> |
||
<code> |
<code>1.3.6.1.4.1.11.2.17.19.3.4.0.1</code><br> |
||
<code> |
<code>1.3.6.1.4.1.11150.3.4.0</code> |
||
<code>.1.3.6.1.4.1.11150.3.4.0.11</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.1</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.3773.0.2</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.2.0.79</code><br> |
|||
<code>.1.3.6.1.4.1.11150.3.4.0.21</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.2.0.9</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.25</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.32</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.4</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.31</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.3</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.3773.0.1</code><br> |
|||
| |
| |
||
<code> |
<code>1.3.6.1.4.1.11.2.17.19.3.4.0.1</code><br> |
||
<code> |
<code>1.3.6.1.4.1.11.2.17.19.3.4.0.4</code><br> |
||
<code> |
<code>1.3.6.1.4.1.11.2.17.19.3.4.0.10</code><br> |
||
<code> |
<code>1.3.6.1.4.1.11150.3.4.0</code><br> |
||
<code> |
<code>1.3.6.1.4.1.11150.3.4.0.1</code> |
||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.4</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.10</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.19</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.22</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.25</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.31</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.19.3.4.0.32</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.3773.0.1</code><br> |
|||
<code>.1.3.6.1.4.1.11.2.17.3773.0.2</code><br> |
|||
<code>.1.3.6.1.4.1.11150.3.4.0.1</code><br> |
|||
<code>.1.3.6.1.4.1.11150.3.4.0.2</code><br> |
|||
<code>.1.3.6.1.4.1.11150.3.4.0.11</code><br> |
|||
<code>.1.3.6.1.4.1.11150.3.4.0.21</code><br> |
|||
|} |
|} |
||
Line 66: | Line 41: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
{{update|C++|the format description and test-case in the task description have been updated}} |
|||
<lang Cpp>#include <string> |
<lang Cpp>#include <string> |
||
#include <vector> |
#include <vector> |
||
Line 155: | Line 133: | ||
</pre> |
</pre> |
||
⚫ | |||
{{update|Elixir|the format description and test-case in the task description have been updated}} |
|||
⚫ | |||
{{works with|Elixir|1.3.1}} |
{{works with|Elixir|1.3.1}} |
||
<lang elixir>defmodule Sort_by_OID do |
<lang elixir>defmodule Sort_by_OID do |
||
Line 216: | Line 195: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
{{update|Haskell|the format description and test-case in the task description have been updated}} |
|||
<lang Haskell>import Data.List ( sortBy , intercalate ) |
<lang Haskell>import Data.List ( sortBy , intercalate ) |
||
Line 288: | Line 270: | ||
# 18 | .1.3.6.1.4.1.11150.3.4.0.21 | |
# 18 | .1.3.6.1.4.1.11150.3.4.0.21 | |
||
</pre> |
</pre> |
||
=={{header|J}}== |
=={{header|J}}== |
||
{{update|J|the format description and test-case in the task description have been updated}} |
|||
Data: |
Data: |
||
Line 344: | Line 327: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
{{update|Lua|the format description and test-case in the task description have been updated}} |
|||
Using the in-built table.sort with a custom compare function. |
Using the in-built table.sort with a custom compare function. |
||
<lang Lua>local OIDs = { |
<lang Lua>local OIDs = { |
||
Line 399: | Line 385: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
{{update|Perl|the format description and test-case in the task description have been updated}} |
|||
<lang perl> |
<lang perl> |
||
Line 484: | Line 472: | ||
</pre> |
</pre> |
||
=={{header|Perl 6}}== |
=={{header|Perl 6}}== |
||
{{update|Perl 6|the format description and test-case in the task description have been updated}} |
|||
{{trans|Perl}} |
{{trans|Perl}} |
||
<lang perl6>use v6; |
<lang perl6>use v6; |
||
Line 546: | Line 536: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
{{update|REXX|the format description and test-case in the task description have been updated}} |
|||
This REXX version doesn't assume a leading decimal point. |
This REXX version doesn't assume a leading decimal point. |
||
<lang rexx>/*REXX program performs a sort of OID (Object IDentifiers ◄── used in Network data). */ |
<lang rexx>/*REXX program performs a sort of OID (Object IDentifiers ◄── used in Network data). */ |
||
Line 634: | Line 627: | ||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
{{update|Ring|the format description and test-case in the task description have been updated}} |
|||
<lang Ring> |
<lang Ring> |
||
Line 781: | Line 777: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{update|zkl|the format description and test-case in the task description have been updated}} |
|||
Translation of http://rosettacode.org/wiki/Natural_sorting#zkl |
Translation of http://rosettacode.org/wiki/Natural_sorting#zkl |
||
Revision as of 12:11, 24 August 2016
Object identifiers (OID) are strings used to identify objects in network data.
Show how to sort a list of OIDs naturally.
- 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 lexicographical with regard to the dot-separated fields, using numeric comparison between fields.
Input (list of strings) | Output (list of strings) |
---|---|
|
|
C++
<lang Cpp>#include <string>
- include <vector>
- include <algorithm>
- include <boost/tokenizer.hpp>
- include <iostream>
std::vector<std::string> splitOnChar ( std::string & s , const char c ) {
typedef boost::tokenizer<boost::char_separator<char>> tokenizer ; std::vector<std::string> parts ; boost::char_separator<char> sep( &c ) ; tokenizer tokens( s , sep ) ; for ( auto it = tokens.begin( ) ; it != tokens.end( ) ; it++ ) parts.push_back( *it ) ; return parts ;
}
bool myCompare ( const std::string & s1 , const std::string & s2 ) {
std::string firstcopy( s1 ) ; std::string secondcopy ( s2 ) ; std::vector<std::string> firstparts( splitOnChar ( firstcopy, '.' ) ) ; std::vector<std::string> secondparts( splitOnChar ( secondcopy, '.' ) ) ; std::vector<int> numbers1( firstparts.size( ) ) ; std::vector<int> numbers2( secondparts.size( ) ) ; std::transform( firstparts.begin( ) , firstparts.end( ) , numbers1.begin( ) ,
[]( std::string st ) { return std::stoi( st , nullptr ) ; } ) ;
std::transform( secondparts.begin( ) , secondparts.end( ) , numbers2.begin( ) ,
[]( std::string st ) { return std::stoi( st , nullptr ) ; } ) ;
auto it1 = numbers1.begin( ) ; auto it2 = numbers2.begin( ) ; while ( *it1 == *it2 ) { it1++ ; it2++ ; } 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.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" } ;
std::sort( arrayOID.begin( ) , arrayOID.end( ) , myCompare ) ; int number = 1 ; for ( std::string s : arrayOID ) { std::cout << "# " ; if ( number < 10 )
std::cout << 0 << number ;
else
std::cout << number ;
std::cout << " | " << s << " |\n" ; number++ ; } return 0 ;
}</lang>
- Output:
# 01 | .1.3.6.1.4.1.11.2.17.19.2.0.9 | # 02 | .1.3.6.1.4.1.11.2.17.19.2.0.79 | # 03 | .1.3.6.1.4.1.11.2.17.19.3.4.0.1 | # 04 | .1.3.6.1.4.1.11.2.17.19.3.4.0.2 | # 05 | .1.3.6.1.4.1.11.2.17.19.3.4.0.3 | # 06 | .1.3.6.1.4.1.11.2.17.19.3.4.0.4 | # 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 |
Elixir
<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.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
] Sort_by_OID.numbers(listOID) |> Enum.with_index |> Enum.each(fn {oid,i} ->
:io.fwrite "# ~2..0w | ~s |~n", [i+1, oid] end)</lang>
- Output:
# 01 | .1.3.6.1.4.1.11.2.17.19.2.0.9 | # 02 | .1.3.6.1.4.1.11.2.17.19.2.0.79 | # 03 | .1.3.6.1.4.1.11.2.17.19.3.4.0.1 | # 04 | .1.3.6.1.4.1.11.2.17.19.3.4.0.2 | # 05 | .1.3.6.1.4.1.11.2.17.19.3.4.0.3 | # 06 | .1.3.6.1.4.1.11.2.17.19.3.4.0.4 | # 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 |
Haskell
<lang Haskell>import Data.List ( sortBy , intercalate )
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" ]
splitString :: Char -> String -> [String] 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] 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
outputLine :: Int -> String -> IO ( ) outputLine counter s = do
putStr "# " if counter < 10 then putStr ("0" ++ show counter ) else putStr ( show counter ) putStr " | ." putStr s putStrLn " |"
main :: IO ( ) main = do
let pairs = zip orderOID [1..length orderOID] mapM_ (\p -> outputLine (snd p) (fst p) ) pairs</lang>
- Output:
# 01 | .1.3.6.1.4.1.11.2.17.19.2.0.9 | # 02 | .1.3.6.1.4.1.11.2.17.19.2.0.79 | # 03 | .1.3.6.1.4.1.11.2.17.19.3.4.0.1 | # 04 | .1.3.6.1.4.1.11.2.17.19.3.4.0.2 | # 05 | .1.3.6.1.4.1.11.2.17.19.3.4.0.3 | # 06 | .1.3.6.1.4.1.11.2.17.19.3.4.0.4 | # 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 |
J
Data:
<lang 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.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
)</lang>
In other words, for each line in that script, remove the spaces and put the rest in a box.
Sorting:
<lang J> >(/: __&".;._1&.>) oids .1.3.6.1.4.1.11.2.17.19.2.0.9 .1.3.6.1.4.1.11.2.17.19.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.19.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 </lang>
In other words, for our sort key, we break the contents of each box by the initial character and treat the remainder as numbers.
We also pull the result out of its boxes for display purposes.
Lua
Using the in-built table.sort with a custom compare function. <lang Lua>local OIDs = {
".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"
}
function compare (a, b)
local aList, bList, Na, Nb = {}, {} for num in a:gmatch("%d+") do table.insert(aList, num) end 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]), tonumber(bList[i]) if Na ~= Nb then return Na < Nb end end
end
table.sort(OIDs, compare) table.foreach(OIDs, print)</lang>
- Output:
1 .1.3.6.1.4.1.11.2.17.19.2.0.9 2 .1.3.6.1.4.1.11.2.17.19.2.0.79 3 .1.3.6.1.4.1.11.2.17.19.3.4.0.1 4 .1.3.6.1.4.1.11.2.17.19.3.4.0.2 5 .1.3.6.1.4.1.11.2.17.19.3.4.0.3 6 .1.3.6.1.4.1.11.2.17.19.3.4.0.4 7 .1.3.6.1.4.1.11.2.17.19.3.4.0.10 8 .1.3.6.1.4.1.11.2.17.19.3.4.0.19 9 .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
Perl
<lang perl>
- !/usr/bin/perl
- --------------------------
- Sort: -OID - Numeric
- Bert Mariani 2016-07-07
- --------------------------
@arrayOID = () ; @arrayOIDSorted = () ;
@arrayOID = (
".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"
);
### One big long line ... made readable @arrayOIDSorted = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [ $_, join , map { sprintf("%8d",$_) } split( /\./, $_) ] } @arrayOID;
print "\nAfter OID Sort \n\n"; $ptrN = 0; $entry = 1;
while ( $arrayOIDSorted[$ptrN] ) { print "$entry | $arrayOIDSorted[$ptrN] |\n" ; $entry++; $ptrN++; }
print "\nEnd OID Sort \n\n";
</lang>
- Output:
1 | .1.3.6.1.4.1.11.2.17.19.2.0.9 | 2 | .1.3.6.1.4.1.11.2.17.19.2.0.79 | 3 | .1.3.6.1.4.1.11.2.17.19.3.4.0.1 | 4 | .1.3.6.1.4.1.11.2.17.19.3.4.0.2 | 5 | .1.3.6.1.4.1.11.2.17.19.3.4.0.3 | 6 | .1.3.6.1.4.1.11.2.17.19.3.4.0.4 | 7 | .1.3.6.1.4.1.11.2.17.19.3.4.0.10 | 8 | .1.3.6.1.4.1.11.2.17.19.3.4.0.19 | 9 | .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 |
Perl 6
<lang perl6>use v6;
.say for sort { $^oid.comb(/\d+/).fmt('%08d') }, <
.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
>;</lang>
- Output:
.1.3.6.1.4.1.11.2.17.19.2.0.9 .1.3.6.1.4.1.11.2.17.19.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.19.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
Alternatively, more golfed:
<lang Perl6>.say for sort *.split('.')».Int, <
...
>;</lang>
Or if using a third-party module is acceptable (input elided):
<lang Perl6>use Sort::Naturally;
.say for sort &naturally, <
...
>;</lang>
REXX
This REXX version doesn't assume a leading decimal point. <lang rexx>/*REXX program performs a sort of OID (Object IDentifiers ◄── used in Network data). */
$= .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
- =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) /*display a fence, sep the before&after*/
call norma 1 /*expand all the internal OID numbers. */ call bSort # /*invoke bubble sort to sort numbers. */ call norma 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: 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 /*Not out─of─order?*/ _=@.j; @.j=@.k; @.k=_; ok=0 /*swap two elements; flag as not done.*/ end /*j*/ end /*m*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/ norma: parse arg LZ; do j=1 for #; x=@.j; y=left(., left(x, 1)==.)
if y==. then x=substr(x,2) /*X have leading dot?*/ do while x\==; parse var x z "." x /*extract number.*/ if LZ then y=y || right(z, w, 0). /*added leading 0's ?*/ else y=y || z+0 || . /*elide " " */ end /*while*/ @.j=strip(y, 'T', .) /*use new Y version.*/ end /*i*/ /*LZ: Leading Zero(es)*/ return /*── ─ ─ */
/*──────────────────────────────────────────────────────────────────────────────────────*/ show: do s=1 for #; say " OID number" right(s, length(#)) arg(1) @.s; end; return</lang> output when using the (internal) default numbers:
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.11150.3.4.0.2 OID number 3 before sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.19 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.22 OID number 6 before sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.2 OID number 7 before sort ───► .1.3.6.1.4.1.11150.3.4.0.11 OID number 8 before sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.1 OID number 9 before sort ───► .1.3.6.1.4.1.11.2.17.3773.0.2 OID number 10 before sort ───► .1.3.6.1.4.1.11.2.17.19.2.0.79 OID number 11 before sort ───► .1.3.6.1.4.1.11150.3.4.0.21 OID number 12 before sort ───► .1.3.6.1.4.1.11.2.17.19.2.0.9 OID number 13 before sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.25 OID number 14 before sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.32 OID number 15 before sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.4 OID number 16 before sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.31 OID number 17 before sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.3 OID number 18 before sort ───► .1.3.6.1.4.1.11.2.17.3773.0.1 ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ OID number 1 after sort ───► .1.3.6.1.4.1.11.2.17.19.2.0.9 OID number 2 after sort ───► .1.3.6.1.4.1.11.2.17.19.2.0.79 OID number 3 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.1 OID number 4 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.2 OID number 5 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.3 OID number 6 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.4 OID number 7 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.10 OID number 8 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.19 OID number 9 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.22 OID number 10 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.25 OID number 11 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.31 OID number 12 after sort ───► .1.3.6.1.4.1.11.2.17.19.3.4.0.32 OID number 13 after sort ───► .1.3.6.1.4.1.11.2.17.3773.0.1 OID number 14 after sort ───► .1.3.6.1.4.1.11.2.17.3773.0.2 OID number 15 after sort ───► .1.3.6.1.4.1.11150.3.4.0.1 OID number 16 after sort ───► .1.3.6.1.4.1.11150.3.4.0.2 OID number 17 after sort ───► .1.3.6.1.4.1.11150.3.4.0.11 OID number 18 after sort ───► .1.3.6.1.4.1.11150.3.4.0.21
Ring
<lang Ring>
/*
+-------------------------------------------------------------- + Program Name : SortOIDNumeric.ring + Date : 2016-07-14 + Author : Bert Mariani + Purpose : Sort OID List in Numeric Order +--------------------------------------------------------------
- /
oldOidList = [
".1.3.6.1.4.1.11150.3.4.0.21", ".1.3.6.1.4.1.11150.3.4.0.11", ".1.3.6.1.4.1.11150.3.4.0.2", ".1.3.6.1.4.1.11150.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.3773.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 See nl + "oldOIDList Before Sort" +nl See oldOidList
#---------------------
delChar = "." nulChar = "" padChar = " " padSize = 6 newDotPadList = []
### Split list into lines for line in oldOidList
### Split line by . into components noDotList = str2list( substr(line, delChar, nl) )
### Pad components with left blanks to make equal size newPadList = PadStringList(noDotList, padChar, padSize)
### Join the components back to a line newDotPadString = JoinStringList(delChar, newPadList)
### Create new list - Alpha Add(newDotPadList, newDotPadString) next
### Sorts Alpha list newDotPadListSorted = sort(newDotPadList)
### SHOW ALPHA INTERMEDIATE OUTPUT See nl + "newDotPadListSorted Intermediate Sort" +nl See newDotPadListSorted
### Remove blanks for original look newOidList = RemovePadCharList( newDotPadListSorted, padChar, nulChar)
###--------------------
### SHOW AFTER SORT - NUMERIC See nl + "newOIDList Final Sort" +nl See newOidList
- --------------------------------------------------------------------
- Function: PadStringList
- newList = PadStringList(oldList, padChar, padSize )
- --------------------------------------------------------------------
Func PadStringList oldList, padChar, padSize
newList = [] for line in oldList newPadSize = padSize - len(line) newLine = Copy( padChar, newPadSize) + line Add(newList, newLine) next
### First line in all blank because of leading dot - remove Del(newList,1)
return newList
- ------------------------------------------------------------
- FUNC JoinStringList
- newString = JoinStringList( joinChar, oldList)
- ------------------------------------------------------------
Func JoinStringList joinChar, OldList
newString = "" for line in OldList newString = newString + joinChar + line next
return newString
- ---------------------------------------------------------------------
- FUNC RemovePadCharList
- newOidList = RemovePadCharList( oldList, padChar, nulChar)
- ---------------------------------------------------------------------
Func RemovePadCharList oldList, padChar, nulChar
newList = [] for line in oldList noPadString = substr(line, padChar, nulChar) Add(newList, noPadString) next
return newList
- -----------------------------------------------------------
>;</lang>
- Output:
.1.3.6.1.4.1.11.2.17.19.2.0.9 .1.3.6.1.4.1.11.2.17.19.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.19.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
zkl
Translation of http://rosettacode.org/wiki/Natural_sorting#zkl
Basically, blow apart each line into a list of numbers and sort that. <lang zkl>fcn sortOIDS(oids){
oids:=oids.pump(List(),fcn(oid){ oid[1,*].split(".").apply("toInt") }); oids.sort( // in place sort fcn(a,b){ // a&b are (x,y,z,...), eg (0,4,2,54)
a.zip(b).reduce(fcn(_,[(a,b)]){ if(a==b)return(True); // continue to next field return(Void.Stop,a<b); },True);
}); oids.pump(List,fcn(a,b,c,etc){ "."+vm.arglist[0].concat(".") }) // back to strings
}</lang> <lang zkl>oids:=List(
".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");
sortOIDS(oids).pump(Console.println);</lang>
- Output:
.1.3.6.1.4.1.11.2.17.19.2.0.9 .1.3.6.1.4.1.11.2.17.19.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.19.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
- Draft Programming Tasks
- C++
- C++ examples needing attention
- Examples needing attention
- Elixir
- Elixir examples needing attention
- Haskell
- Haskell examples needing attention
- J
- J examples needing attention
- Lua
- Lua examples needing attention
- Perl
- Perl examples needing attention
- Perl 6
- Perl 6 examples needing attention
- REXX
- REXX examples needing attention
- Ring
- Ring examples needing attention
- Zkl
- Zkl examples needing attention