Sort a list of object identifiers: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|REXX}}: changed/added comments and whitespace, added whitespace to the ouput.)
Line 134: Line 134:
=={{header|Haskell}}==
=={{header|Haskell}}==
<lang Haskell>import Data.List ( sort , intercalate )
<lang Haskell>import Data.List ( sort , intercalate )

oid :: [String]
oid = ["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"]


splitString :: Eq a => (a) -> [a] -> [[a]]
splitString :: Eq a => (a) -> [a] -> [[a]]
Line 152: Line 144:
convertIntListToString = intercalate "." . map show
convertIntListToString = intercalate "." . map show


orderOID :: [String]
orderOID :: [String] -> [String]
orderOID = map convertIntListToString . sort .
orderOID = map convertIntListToString . sort . map ( map read . splitString '.' )

map ( map read . splitString '.' ) $ oid
oid :: [String]
oid = ["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"]


main :: IO ( )
main :: IO ( )
main = do
main = do
mapM_ putStrLn orderOID</lang>
mapM_ putStrLn $ orderOID oid</lang>


{{out}}
{{out}}

Revision as of 18:47, 25 February 2017

Sort a list of object identifiers is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Object identifiers (OID) are strings used to identify objects in network data.

Show how to sort a list of OIDs, in their natural sort order.

Details
  • 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.
Test case
Input (list of strings) Output (list of strings)

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

Related tasks

C++

<lang Cpp>#include <string>

  1. include <vector>
  2. include <algorithm>
  3. include <boost/tokenizer.hpp>
  4. 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++ ;
  }
  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.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" } ;
  std::sort( arrayOID.begin( ) , arrayOID.end( ) , myCompare ) ;
  for ( std::string s : arrayOID ) 
     std::cout << s << '\n' ;
  return 0 ;

}</lang>

Output:
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

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/1)
   end)
 end

end

~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.numbers |> Enum.each(fn oid -> IO.puts oid end)</lang>

Output:
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

Haskell

<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 = intercalate "." . map show

orderOID :: [String] -> [String] orderOID = map convertIntListToString . sort . map ( map read . splitString '.' )

oid :: [String] oid = ["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"]

main :: IO ( ) main = do

  mapM_ putStrLn $ orderOID oid</lang>
Output:
3.6.1.4.1.11.2.17.5.2.0.79
3.6.1.4.1.11.2.17.19.3.4.0.1
3.6.1.4.1.11.2.17.19.3.4.0.4
3.6.1.4.1.11.2.17.19.3.4.0.10
3.6.1.4.1.11150.3.4.0
3.6.1.4.1.11150.3.4.0.1

(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)

<lang haskell>import Data.Text (pack, split, unpack) import Data.List (sort, intercalate)

-- SORTING OBJECT IDENTIFIERS ------------------------------------------------ oidSort :: [String] -> [String] oidSort =

 (intercalate "." <$>) .
 ((show <$>) <$>) . sort . ((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"
   ]</lang>
Output:
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

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:

<lang haskell>import Data.List.Split (splitOn) import Data.List (sort, intercalate)

-- SORTING OBJECT IDENTIFIERS ------------------------------------------------ oidSort :: [String] -> [String] oidSort =

 (intercalate "." <$>) .
 ((show <$>) <$>) . sort . ((readInt <$>) <$>) . (splitOn "." <$>)</lang>

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.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

)</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.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 </lang>

In other words, for our sort key, we break the contents of each box by an initial '.' and treat the remainder as numbers.

We also pull the result out of its boxes for display purposes.

Kotlin

<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"))

}</lang>

Output:
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

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.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 = {}, {}
   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]) or 0, tonumber(bList[i]) or 0
       if Na ~= Nb then return Na < Nb end
   end

end

table.sort(OIDs, compare) for _, oid in pairs(OIDs) do print(oid) end</lang>

Output:
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

Perl

<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
   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

);

my @sorted =

   map { $_->[0] }
   sort { $a->[1] cmp $b->[1] }
   map { [$_, join , map { sprintf "%8d", $_ } split /\./, $_] }
   @OIDs;

print "$_\n" for @sorted;</lang>

Output:
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

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.

<lang perl>my @sorted =

   map { $_->[0] }
   sort { $a->[1] cmp $b->[1] }
   map { [$_, eval "v$_"] }
   @OIDs;</lang>

Perl 6

The sort 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.

<lang perl6>.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
   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

>;</lang>

Output:
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

Alternatively, using the sprintf-based approach used by the Perl solution, for comparison (input elided):

<lang perl6>.say for sort *.split('.').fmt('%08d'), <...>;</lang>

Or if using a third-party module is acceptable:

<lang Perl6>use Sort::Naturally;

.say for sort &naturally, <...>;</lang>

Python

We need to split the input and map each part to int otherwise elements gets compared as a string <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)

</lang>

Racket

<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")))</lang>

Tests run with no output, indicating success.

REXX

This REXX version supports the new and old format   (supports 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.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. =words($) /*#: the number of OIDs in the $ list.*/
            do i=1  for #;   @.i=word($, i)     /*build the @ array from each word in $*/
            end   /*i*/

L=length(#) /*length of the number of words in $. */ a=translate($, , .); q=words(a) /*remove all the decimal points in $. */ w=0 /*W: the widest decimal number in A. */

    do k=1  for q;  w=max(w, length(word(a,k))) /*find width of  widest  number in  A, */
    end   /*k*/                                 /*    (after decimal points have       */
                                                /*     been replaced with blanks).     */

call show 'before sort ───► ' /*display the @ array before sorting.*/

    say copies('░', 79)                         /*display fence, separate 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: 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; _=j+1; if @.j>@._  then parse value @.j @._ 0  with  @._ @.j ok
           end   /*j*/                          /* [↑]  swap two out─of─order elements.*/
        end      /*m*/;          return

/*──────────────────────────────────────────────────────────────────────────────────────*/ norma: arg LZ; do j=1 for #; x=@.j; y=left(.,left(x,1)==.) /*construct Y version.*/

                if y==.  then x=substr(x, 2)                     /*X  have leading dot?*/
                        do  while x\==;  parse var  x  z "." x /*extract the number. */
                        if LZ  then y=y || right(z, w, 0).       /*added leading  0's ?*/
                               else y=y || z+0     ||    .       /*elide    "      "   */
                        end   /*while*/                          /* [↑]  Y  is now adj.*/
                @.j=strip(y, 'T', .)                             /*use new  Y  version.*/
                end           /*j*/                              /*LZ: Leading Zero(es)*/
      return                                                     /*──  ─       ─       */

/*──────────────────────────────────────────────────────────────────────────────────────*/ show: do s=1 for #; say right("OID number",20) right(s,L) 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.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

Ring

This example needs updating due to a modification in the task. Please examine and fix the code if needed, then remove this message.

Details: the format description and test-case in the task description have been updated

<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


      1. --------------------------------------------------------------------
      2. Function: PadStringList
      3. newList = PadStringList(oldList, padChar, padSize )
      4. --------------------------------------------------------------------

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

      1. ------------------------------------------------------------
      2. FUNC JoinStringList
      3. newString = JoinStringList( joinChar, oldList)
      4. ------------------------------------------------------------

Func JoinStringList joinChar, OldList

   newString = ""
   for line in OldList
       newString = newString + joinChar + line
   next

return newString

      1. ---------------------------------------------------------------------
      2. FUNC RemovePadCharList
      3. newOidList = RemovePadCharList( oldList, padChar, nulChar)
      4. ---------------------------------------------------------------------

Func RemovePadCharList oldList, padChar, nulChar

   newList = []
   for line in oldList
         noPadString = substr(line, padChar, nulChar)
       Add(newList, noPadString)
   next

return newList

      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

Ruby

<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}</lang>

Output:
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

Sidef

<lang ruby>func sort_OIDs(ids) {

   ids.sort_by { |id|
       id.split('.').map { Num(_) }
   }

}

var OIDs = %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_OIDs(OIDs).each { .say }</lang>

Output:
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

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 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") });
  oids.sort(  // in place sort
     fcn(a,b){ // a & b are (x,y,z,...-1), eg (0,4,2,54,-1), (4,6,-1)

a.zip(b).reduce(fcn(_,[(a,b)]){ // if one list longer, zip truncates if(a==b) return(True); // continue to next field return(Void.Stop,a<b); // OIDa<OIDb == cmp this field },True);

     });
  oids.pump(List,fcn(list){ list[0,-1].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.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=sortOIDS(oids); oids.pump(Console.println); // print one OID per line</lang>

Output:
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