deep_enumerable 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/deep_enumerable.rb +54 -26
  3. metadata +2 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b740602088c959f7bd2f0fd8e97bcda800422d95
4
- data.tar.gz: 379a9012bde4242061828a13fa2b8a43c46b20db
3
+ metadata.gz: edfce635bf315a5acf694212562adf0ef697c529
4
+ data.tar.gz: e484f7707c0b176146cd47dbd9087b51e36f32a2
5
5
  SHA512:
6
- metadata.gz: 690880c051b9e1b2242cdb641c2f24b7c364698c8c8f4ccef872a552f4414498e9dae6d101871709498b8b652e144aea66102306a3477cb988cdc0dde56e1b4b
7
- data.tar.gz: 49f3eda13d3342971298260cc5530a976ee8f94f77e3da5c6ebe9563e633598b25f16081044adc2e40397483d6b37f5ea17ce79de0b2c8c98671a384a9935761
6
+ metadata.gz: 6cf82e979b450159af3ebf13450b8b559598660423359c21b3d8b646916d4aaf3d06cc91145173cffb8e167503a7bb9e0fbbc0eb514edc19af3e90db0c913023
7
+ data.tar.gz: 2fce4f64b669e36381bee1c6ccc1cf10d99e025ee15a35521ef775508aeac6e5ced2adcfac17eda05ac1b86e6db205f4e0134f098135db211079166b82b72a7c
@@ -41,7 +41,7 @@ module DeepEnumerable
41
41
  # @example
42
42
  # >> alice = {:name=>"alice", :age=>26}
43
43
  # >> bob = {:name=>"bob", :age=>26}
44
- # >> alice.deep_diff(bob)
44
+ # >> alice.deep_diff_symmetric(bob)
45
45
  # => {:name=>["alice", "bob"]}
46
46
  #
47
47
  # >> bob = {:friends=>["alice","carol"]}
@@ -123,8 +123,8 @@ module DeepEnumerable
123
123
  # @return a DeepEnumerable representing the subtree specified by the query key
124
124
  #
125
125
  def deep_get(key)
126
- if nested_key?(key)
127
- key_head, key_tail = split_key(key)
126
+ if DeepEnumerable::nested_key?(key)
127
+ key_head, key_tail = DeepEnumerable::split_key(key)
128
128
  if self[key_head].respond_to?(:deep_get)
129
129
  self[key_head].deep_get(key_tail)
130
130
  else
@@ -307,31 +307,36 @@ module DeepEnumerable
307
307
  end
308
308
 
309
309
  ##
310
- # Update a DeepEnumerable, indexed by a deep-key
310
+ # Update a DeepEnumerable, indexed by an Array or Hash.
311
+ #
311
312
  # Intermediate values are created when necessary, with the same type as its parent.
312
313
  #
313
314
  # @example
314
315
  # >> [].deep_set({1 => 2}, 3)
315
316
  # => [nil, [nil, nil, 3]]
316
- # >> {}.deep_set({1 => 2}, 3)
317
- # => {1=>{2=>3}}
317
+ # >> {}.deep_set([1, 2, 3], 4)
318
+ # => {1=>{2=>{3=>4}}}
318
319
  #
319
320
  # @return (tentative) returns the object that's been modified. Warning: This behavior is subject to change.
320
321
  #
321
322
  def deep_set(key, val)
322
- if nested_key?(key)
323
- key_head, key_tail = split_key(key)
324
- if self[key_head].respond_to?(:deep_set)
325
- self[key_head].deep_set(key_tail, val)
326
- self
323
+ if DeepEnumerable::nested_key?(key)
324
+ key_head, key_tail = DeepEnumerable::split_key(key)
325
+
326
+ if key_tail.nil?
327
+ self[key_head] = val
327
328
  else
328
- self[key_head] = empty.deep_set(key_tail, val)
329
- self
329
+ if self[key_head].respond_to?(:deep_set)
330
+ self[key_head].deep_set(key_tail, val)
331
+ else
332
+ self[key_head] = empty.deep_set(key_tail, val)
333
+ end
330
334
  end
331
- else
335
+ elsif !key.nil? # don't index on nil
332
336
  self[key] = val
333
- self #SHOULD? return val instead of self
334
337
  end
338
+
339
+ self #SHOULD? return val instead of self
335
340
  end
336
341
 
337
342
  ##
@@ -446,7 +451,6 @@ module DeepEnumerable
446
451
  ##
447
452
  # The primary iterator of a DeepEnumerable
448
453
  # If this method is implemented DeepEnumerable can construct every other method in terms of shallow_each.
449
- #TODO test this
450
454
  def shallow_each(&block)
451
455
  shallow_key_value_pairs.each(&block)
452
456
  end
@@ -466,7 +470,7 @@ module DeepEnumerable
466
470
  def depth_first_map(ancestry=[])
467
471
  shallow_each.flat_map do |key, val|
468
472
  full_ancestry = ancestry + [key]
469
- full_key = deep_key_from_array(full_ancestry) #TODO this is an n^2 operation
473
+ full_key = DeepEnumerable::deep_key_from_array(full_ancestry) #TODO this is an n^2 operation
470
474
 
471
475
  if val.respond_to?(:depth_first_map, true) # Search protected methods as well
472
476
  val.depth_first_map(full_ancestry)
@@ -477,7 +481,7 @@ module DeepEnumerable
477
481
  end
478
482
 
479
483
  # Everything below should be a class method, but Ruby method visibility is a nightmare
480
- def deep_key_from_array(array)
484
+ def self.deep_key_from_array(array)
481
485
  if array.size > 1
482
486
  {array.first => deep_key_from_array(array.drop(1))}
483
487
  else
@@ -485,19 +489,43 @@ module DeepEnumerable
485
489
  end
486
490
  end
487
491
 
488
- def nested_key?(key)
489
- key.is_a?(Hash)
492
+ # DeepEnumerable keys are represented as hashes, this function
493
+ # converts them to arrays for convenience
494
+ def self.deep_key_to_array(key)
495
+ if DeepEnumerable::nested_key?(key)
496
+ head, tail = split_key(key)
497
+ [head] + deep_key_to_array(tail)
498
+ elsif key.nil?
499
+ []
500
+ else
501
+ [key]
502
+ end
503
+ end
504
+
505
+ def self.nested_key?(key)
506
+ key.is_a?(Hash) || key.is_a?(Array)
490
507
  end
491
508
 
492
509
  # Disassembles a key into its head and tail elements
493
510
  #
494
- # for example: {a: {0 => :a}} goes to [:a, {0 => :a}]
495
- def split_key(key)
511
+ # @example
512
+ # >> DeepEnumerable.split_key({a: {0 => :a}})
513
+ # => [:a, {0 => :a}]
514
+ # >> DeepEnumerable.split_key([a: [0 => :a]])
515
+ # => [a:, [0, :a]]
516
+ #
517
+ def self.split_key(key)
496
518
  case key
497
519
  when Hash then
498
- key_head = key.keys.first
499
- key_tail = key[key_head]
500
- [key_head, key_tail]
520
+ key_head = key.keys.first
521
+ key_tail = key[key_head]
522
+ [key_head, key_tail]
523
+ when Array then
524
+ case key.size
525
+ when 0 then [nil, nil]
526
+ when 1 then [key[0], nil]
527
+ else [key[0], key.drop(1)]
528
+ end
501
529
  when nil then [nil, nil]
502
530
  else [key, nil]
503
531
  end
@@ -507,7 +535,7 @@ module DeepEnumerable
507
535
  #
508
536
  # for example: {a: {b: :c}} goes to :c
509
537
  def self.leaf_key(key)
510
- key.is_a?(Hash) ? leaf_key(key) : key
538
+ nested_key?(key) ? leaf_key(split_key(key)[1]) : key
511
539
  end
512
540
  end
513
541
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deep_enumerable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Gopstein
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-08 00:00:00.000000000 Z
11
+ date: 2015-12-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A library for manipulating nested collections. See https://github.com/dgopstein/deep_enumerable
14
14
  for details
@@ -43,4 +43,3 @@ signing_key:
43
43
  specification_version: 4
44
44
  summary: A library for manipulating nested collections
45
45
  test_files: []
46
- has_rdoc: