home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Networking / nmap-5.00-setup.exe / nselib / listop.lua < prev    next >
Text File  |  2009-07-06  |  5KB  |  180 lines

  1. --- Functional-style list operations.
  2. --
  3. -- People used to programming in functional languages, such as Lisp
  4. -- or Haskell, appreciate their handling of lists very much. The
  5. -- <code>listop</code> module tries to bring much of the functionality from
  6. -- functional languages to Lua using Lua's central data structure, the table, as
  7. -- a base for its list operations. Highlights include a <code>map</code>
  8. -- function applying a given function to each element of a list. 
  9. -- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
  10.  
  11. module(... or "listop", package.seeall)
  12.  
  13. --[[
  14. --
  15. Functional programming style 'list' operations
  16.  
  17.     bool    is_empty(list)
  18.     bool    is_list(value)
  19.  
  20.     value    apply(function, list)
  21.     list    map(function, list)
  22.     list    filter(function, list)
  23.     list    flatten(list)
  24.     list    append(list1, list2)
  25.     list    cons(value1, value2)
  26.     list    reverse(list)
  27.  
  28.     value    car(list)
  29.     value    ncar(list, x)
  30.     list    cdr(list)
  31.     list    ncdr(list, x)
  32.     
  33.     where 'list' is an indexed table 
  34.     where 'value' is an lua datatype
  35. --]]
  36.  
  37. --- Returns true if the given list is empty.
  38. -- @param l A list.
  39. -- @return True or false.
  40. function is_empty(l)
  41.   return #l == 0 and true or false;
  42. end
  43.  
  44. --- Returns true if the given value is a list (or rather a table).
  45. -- @param l Any value.
  46. -- @return True or false.
  47. function is_list(l)
  48.   return type(l) == 'table' and true or false;
  49. end
  50.  
  51. --- Calls <code>f</code> for each element in the list. The returned list
  52. --contains the results of each function call.
  53. -- @usage
  54. -- listop.map(tostring,{1,2,true}) --> {"1","2","true"}
  55. -- @param f The function to call.
  56. -- @param l A list.
  57. -- @return List of function results.
  58. function map(f, l) 
  59.     local results = {}
  60.     for _, v in ipairs(l) do
  61.         results[#results+1] = f(v);
  62.     end
  63.     return results;
  64. end
  65.  
  66. --- Calls the function with all the elements in the list as the parameters.
  67. -- @usage
  68. -- listop.apply(math.max,{1,5,6,7,50000}) --> 50000
  69. -- @param f The function to call.
  70. -- @param l A list.
  71. -- @return Results from <code>f</code>.
  72. function apply(f, l)
  73.   return f(unpack(l))
  74. end
  75.  
  76. --- Returns a list containing only those elements for which a predicate
  77. -- function returns true.
  78. --
  79. -- The predicate has to be a function taking one argument and returning
  80. -- a Boolean. If it returns true, the argument is appended to the return value
  81. -- of filter.
  82. -- @usage
  83. -- listop.filter(isnumber,{1,2,3,"foo",4,"bar"}) --> {1,2,3,4}
  84. -- @param f The function.
  85. -- @param l The list.
  86. -- @return Filtered list.
  87. function filter(f, l) 
  88.   local results = {}
  89.   for i, v in ipairs(l) do
  90.       if(f(v)) then
  91.          results[#results+1] = v;
  92.        end
  93.   end
  94.   return results
  95. end
  96.  
  97. --- Fetch the first element of a list.
  98. -- @param l The list.
  99. -- @return The first element.
  100. function car(l)
  101.   return l[1]
  102. end
  103.  
  104. --- Fetch all elements following the first in a new list.
  105. -- @param l The list.
  106. -- @return Elements after the first.
  107. function cdr(l)
  108.   return {unpack(l, 2)}
  109. end
  110.  
  111. --- Fetch element at index <code>x</code> from <code>l</code>.
  112. -- @param l The list.
  113. -- @param x Element index.
  114. -- @return Element at index <code>x</code> or at index <code>1</code> if
  115. -- <code>x</code> is not given.
  116. function ncar(l, x)
  117.   return l[x or 1];
  118. end
  119.  
  120. --- Fetch all elements following the element at index <code>x</code>.
  121. -- @param l The list.
  122. -- @param x Element index.
  123. -- @return Elements after index <code>x</code> or after index <code>1</code> if
  124. -- <code>x</code> is not given.
  125. function ncdr(l, x) 
  126.   return {unpack(l, x or 2)};
  127. end
  128.  
  129. --- Prepend a value or list to another value or list.
  130. -- @param v1 value or list.
  131. -- @param v2 value or list.
  132. -- @return New list.
  133. function cons(v1, v2)
  134.     return{ is_list(v1) and {unpack(v1)} or v1, is_list(v2) and {unpack(v2)} or v2}
  135. end
  136.  
  137. --- Concatenate two lists and return the result.
  138. -- @param l1 List.
  139. -- @param l2 List.
  140. -- @return List.
  141. function append(l1, l2)
  142.     local results = {unpack(l1)}
  143.  
  144.     for _, v in ipairs(l2) do
  145.          results[#results+1] = v;
  146.     end
  147.     return results
  148. end
  149.  
  150. --- Return a list in reverse order.
  151. -- @param l List.
  152. -- @return Reversed list.
  153. function reverse(l)
  154.     local results = {}
  155.     for i=#l, 1, -1 do
  156.         results[#results+1] = l[i];
  157.     end
  158.     return results
  159. end
  160.  
  161. --- Return a flattened version of a list. The flattened list contains
  162. -- only non-list values.
  163. -- @usage
  164. -- listop.flatten({1,2,3,"foo",{4,5,{"bar"}}}) --> {1,2,3,"foo",4,5,"bar"}
  165. -- @param l The list to flatten.
  166. -- @return Flattened list.
  167. function flatten(l)
  168.     local function flat(r, t)
  169.         for i, v in ipairs(t) do
  170.             if(type(v) == 'table') then
  171.                 flat(r, v)
  172.             else
  173.                 table.insert(r, v)
  174.             end
  175.         end
  176.         return r
  177.     end
  178.     return flat({}, l)
  179. end
  180.