PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/stl/core/src/list.coffee

http://github.com/MadRabbit/lovely.io
CoffeeScript | 152 lines | 45 code | 19 blank | 88 comment | 2 complexity | 8704f5f72227836bdd58be21f22896e6 MD5 | raw file
  1. #
  2. # The magic list of Lovely IO
  3. #
  4. # The goal in here is to provide a quick, steady and inheritable
  5. # JavaScript 1.7 Array like interface with some additional
  6. # features so that we could iterate through anything in a civilized
  7. # maner without tempering with the JavaScript core.
  8. #
  9. # Copyright (C) 2011-2012 Nikolay Nemshilov
  10. #
  11. class List extends Array
  12. #
  13. # Basic constructor
  14. #
  15. # @param {mixed} iterable list
  16. # @return void
  17. #
  18. constructor: (items)->
  19. unless items is undefined
  20. Array_splice.apply(@, [0,0].concat(items))
  21. return @
  22. #
  23. # Returns a slice of the list
  24. #
  25. # @param {Number} start index
  26. # @param {Number} end index
  27. # @return {List} new slice
  28. #
  29. slice: ->
  30. new @constructor(Array_slice.apply(@, arguments))
  31. #
  32. # Array#concat like method
  33. #
  34. # @param {Array} items to add
  35. # @return {List} new
  36. #
  37. concat: (items)->
  38. new @constructor(A(@).concat(A(items)))
  39. ##
  40. # The standard `forEaech` equivalent
  41. #
  42. # @param {mixed} method name or a callback function
  43. # @param {mixed} scope object or the method param
  44. # @return {List} this
  45. #
  46. forEach: ->
  47. List_call(Array_forEach, @, arguments)
  48. return @
  49. #
  50. # Maps the result of the callback function work into
  51. # a new {List} object
  52. #
  53. # @param {mixed} method name or a callback function
  54. # @param {mixed} scope object or the method param
  55. # @return {List} new
  56. #
  57. map: ->
  58. new List(List_call(Array_map, @, arguments))
  59. #
  60. # Creates a new list that has only matching items in it
  61. #
  62. # @param {mixed} method name or a callback function
  63. # @param {mixed} scope object or the method param
  64. # @return {List} new
  65. #
  66. filter: ->
  67. new @constructor(List_call(Array_filter, @, arguments))
  68. #
  69. # Creates a new list that has no matching items in it
  70. #
  71. # @param {mixed} method name or a callback function
  72. # @param {mixed} scope object or the method param
  73. # @return {List} new
  74. #
  75. reject: ->
  76. new @constructor(List_call(Array_reject, @, arguments))
  77. #
  78. # Checks if some of the items on the list are kinda `true`
  79. #
  80. # @param {mixed} callback or a method name
  81. # @param {mixed} scope object or the method param
  82. # @return {Boolean} check result
  83. #
  84. some: ->
  85. List_call(Array_some, @, arguments)
  86. #
  87. # Checks if every item on the list are kinda `true`
  88. #
  89. # @param {mixed} callback or a method name
  90. # @param {mixed} scope object or the method param
  91. # @return {Boolean} check result
  92. #
  93. every: ->
  94. List_call(Array_every, @, arguments)
  95. #
  96. # Converts the list into an instance or {Array}
  97. #
  98. # @return {Array} new
  99. #
  100. toArray: -> A(@)
  101. #
  102. # Debugability improver
  103. #
  104. # @return {String} representation
  105. #
  106. toString: -> "#<List [#{A(@)}]>"
  107. # private
  108. Array_proto = Array.prototype
  109. # the rest of the standard Array methods and their replacements for old browsers
  110. Array_slice = Array_proto.slice
  111. Array_splice = Array_proto.splice
  112. Array_forEach = Array_proto.forEach
  113. Array_map = Array_proto.map
  114. Array_filter = Array_proto.filter
  115. Array_reject = (callback, scope)->
  116. Array_filter.call @, ->
  117. !callback.apply scope, arguments
  118. Array_some = Array_proto.some
  119. Array_every = Array_proto.every
  120. #
  121. # calls the array method on the list with the arguments
  122. # we need this wrapper to handle the calls by name feature
  123. #
  124. List_call = (method, list, args) ->
  125. # handling the calls by name
  126. if typeof(args[0]) is 'string'
  127. call_args = A(args)
  128. attr_name = call_args.shift()
  129. if list.length isnt 0 and typeof(list[0][attr_name]) is 'function'
  130. args = [ (item) -> item[attr_name].apply(item, call_args) ]
  131. else
  132. args = [ (item) -> item[attr_name] ]
  133. method.apply(list, args)