objects.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. //
  2. // adds all the fields from obj2 onto obj1
  3. //
  4. var each = exports.each = function (obj,iterator){
  5. var keys = Object.keys(obj)
  6. keys.forEach(function (key){
  7. iterator(obj[key],key,obj)
  8. })
  9. }
  10. var merge = exports.merge = function (a, b) {
  11. if(arguments.length <= 1)
  12. return a
  13. if(a == null)
  14. return merge.apply(null, [].slice.call(arguments, 1))
  15. if(b != null)
  16. each(b, function (v,k){
  17. a[k] = v
  18. })
  19. return merge.apply(null, [a].concat([].slice.call(arguments, 2)))
  20. }
  21. /*var merge = exports.merge = function (){
  22. var args = [].slice.call(arguments)
  23. var obj1 = null, obj2 = null
  24. while (args.length && obj1 == null) //skip null and undefined
  25. obj1 = args.shift()
  26. while(args.length) {
  27. obj2 = null
  28. while (args.length && obj1 == null) //skip null and undefined
  29. obj2 = args.shift()
  30. var keys = Object.keys(obj2)
  31. each(obj2, function (v,k){
  32. obj1[k] = v
  33. })
  34. }
  35. return obj1
  36. }*/
  37. var RX = /sadf/.constructor
  38. function rx (iterator ){
  39. return iterator instanceof RX ? function (str) {
  40. var m = iterator.exec(str)
  41. return m && (m[1] ? m[1] : m[0])
  42. } : iterator
  43. }
  44. var times = exports.times = function () {
  45. var args = [].slice.call(arguments)
  46. , iterator = rx(args.pop())
  47. , m = args.pop()
  48. , i = args.shift()
  49. , j = args.shift()
  50. , diff, dir
  51. , a = []
  52. i = 'number' === typeof i ? i : 1
  53. diff = j ? j - i : 1
  54. dir = i < m
  55. if(m == i)
  56. throw new Error('steps cannot be the same: '+m+', '+i)
  57. for (; dir ? i <= m : m <= i; i += diff)
  58. a.push(iterator(i))
  59. return a
  60. }
  61. var map = exports.map = function (obj, iterator){
  62. iterator = rx(iterator)
  63. if(Array.isArray(obj))
  64. return obj.map(iterator)
  65. if('number' === typeof obj)
  66. return times.apply(null, [].slice.call(arguments))
  67. //return if null ?
  68. var keys = Object.keys(obj)
  69. , r = {}
  70. keys.forEach(function (key){
  71. r[key] = iterator(obj[key],key,obj)
  72. })
  73. return r
  74. }
  75. var findReturn = exports.findReturn = function (obj, iterator) {
  76. iterator = rx(iterator)
  77. if(obj == null)
  78. return
  79. var keys = Object.keys(obj)
  80. , l = keys.length
  81. for (var i = 0; i < l; i ++) {
  82. var key = keys[i]
  83. , value = obj[key]
  84. var r = iterator(value, key)
  85. if(r) return r
  86. }
  87. }
  88. var find = exports.find = function (obj, iterator) {
  89. iterator = rx(iterator)
  90. return findReturn (obj, function (v, k) {
  91. var r = iterator(v, k)
  92. if(r) return v
  93. })
  94. }
  95. var findKey = exports.findKey = function (obj, iterator) {
  96. iterator = rx(iterator)
  97. return findReturn (obj, function (v, k) {
  98. var r = iterator(v, k)
  99. if(r) return k
  100. })
  101. }
  102. var filter = exports.filter = function (obj, iterator){
  103. iterator = rx (iterator)
  104. if(Array.isArray(obj))
  105. return obj.filter(iterator)
  106. var keys = Object.keys(obj)
  107. , r = {}
  108. keys.forEach(function (key){
  109. var v
  110. if(iterator(v = obj[key],key,obj))
  111. r[key] = v
  112. })
  113. return r
  114. }
  115. var mapKeys = exports.mapKeys = function (ary, iterator){
  116. var r = {}
  117. iterator = rx(iterator)
  118. each(ary, function (v,k){
  119. r[v] = iterator(v,k)
  120. })
  121. return r
  122. }
  123. var mapToArray = exports.mapToArray = function (ary, iterator){
  124. var r = []
  125. iterator = rx(iterator)
  126. each(ary, function (v,k){
  127. r.push(iterator(v,k))
  128. })
  129. return r
  130. }
  131. diff = exports.diff = function (old, nw) {
  132. var ab = deepMerge (nw, old)
  133. , s = {}
  134. each(ab, function (ignore, k) {
  135. //if the property is not in the new object, it must have been deleted.
  136. if (nw[k] == null)
  137. s[k] = null //null on a diff means to delete that property.
  138. else if ('object' === typeof nw[k] && 'object' === typeof old[k] && old[k])
  139. s[k] = diff(old[k], nw[k])
  140. else if (nw[k] !== old[k])
  141. s[k] = nw[k] === undefined ? null : nw[k]
  142. })
  143. return s
  144. }
  145. patch = exports.patch = function (old, ptch) {
  146. var nw = deepMerge({}, old)
  147. each(ptch, function (ignore, k) {
  148. //if the property is not in the new object, it must have been deleted.
  149. if (ptch[k] === null)
  150. delete nw[k]
  151. else if ('object' === typeof ptch[k])
  152. nw[k] = patch(old[k], ptch[k])
  153. else
  154. nw[k] = ptch[k]
  155. })
  156. return nw
  157. }
  158. deepMerge = exports.deepMerge = function (old, nw) {
  159. var ab = merge({}, nw, old)
  160. , s = Array.isArray(nw) ? [] : {}
  161. each(ab, function (ignore, k) { //on each key in ab,
  162. s[k] = (nw[k] === undefined ? old[k] : nw[k])
  163. if ('object' === typeof nw[k] && 'object' === typeof old[k] && old[k] && nw[k] && old[k]) {
  164. s[k] = deepMerge (old[k], nw[k])
  165. }
  166. })
  167. return s
  168. }
  169. var path = exports.path = function (object, path) {
  170. for (var i in path) {
  171. if(object == null) return undefined
  172. var key = path[i]
  173. object = object[key]
  174. }
  175. return object
  176. }
  177. var eachPath = exports.eachPath = function (object, opts, iterator) {
  178. // function iterator (value, path)
  179. }
  180. /*
  181. NOTE: naive implementation.
  182. `match` must not contain circular references.
  183. */
  184. var has = exports.has = function (obj, match) {
  185. if(obj == null && match != null)
  186. return false
  187. for (var key in match) {
  188. //deep/complex checks
  189. if('object' == typeof match[key]) {
  190. if(!has(obj[key], match[key]))
  191. return false
  192. } else if ('function' == typeof match[key]) {
  193. if (!match[key](obj[key]))
  194. return false
  195. } else if(match[key] !== obj[key])
  196. return false
  197. //if match is a function, apply it to the corrisponding obj[key]
  198. }
  199. return true
  200. }
  201. var setPath = exports.setPath = function (object, path, value) {
  202. for (var i in path) {
  203. var key = path[i]
  204. if(object[key] == null) object[key] = (
  205. i + 1 == path.length ? value : {}
  206. )
  207. object = object[key]
  208. }
  209. }
  210. var enqueue = exports.enqueue = function (queue, value) {
  211. if(!~queue.indexOf(value))
  212. return queue.push(value), true
  213. return false
  214. }