deep_enumerable 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: