traipse 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in traipse.gemspec
4
+ gemspec
5
+ gem 'rspec'
@@ -0,0 +1,33 @@
1
+ = Traipse
2
+
3
+ Traipse allows you to address a data structure with a dot notated string. This is useful for extracting certain nodes
4
+ in a data structure (expecially JSON-parsed) and storing the 'path' to those nodes in a database.
5
+
6
+ == Installation
7
+
8
+ Traipse is available as a RubyGem:
9
+
10
+ gem install traipse
11
+
12
+ === Example
13
+
14
+ data = {
15
+ "name" => "Percival",
16
+ "board" => {
17
+ "name" => "cats"
18
+ },
19
+ "categories" => [
20
+ { "name" => "animals" },
21
+ { "name" => "kitties" },
22
+ { "name" => "robots" },
23
+ ]
24
+ }
25
+
26
+ Traipse.find( data, 'name' ) # [ "Percival" ]
27
+ Traipse.find( data, 'board.name' ) # [ "cats" ]
28
+ Traipse.find( data, 'categories.name' ) # [ "animals", "kitties", "robots" ]
29
+ Traipse.find( data, '*.name' ) # [ "cats", "animals", "kitties", "robots" ]
30
+
31
+ == Authors
32
+
33
+ * Pawel Szymczykowski
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,46 @@
1
+ require "traipse/version"
2
+
3
+ module Traipse
4
+
5
+ SEPARATOR = '.'
6
+
7
+ # Find a needle in a haystack using something akin to JSON dot syntax
8
+ # ex: Traipse.find( data, 'cat.name' ) # similar to data['cat']['name']
9
+ def self.find( object, path )
10
+ return _find( object, path.split( SEPARATOR ) )
11
+ end
12
+
13
+ def self._find( object, path, results=[] ) # :nodoc:
14
+ key, *rest = path
15
+
16
+ # Oops.. no key? Hands a path of '*'
17
+ return [ object ] unless key
18
+
19
+ # What happens if we miss a key?
20
+ return [] unless object.is_a?( Hash )
21
+
22
+ # Handle wildcard hash keys
23
+ if key == '*'
24
+ object.keys.each do |subkey|
25
+ results += _find( object, [ subkey, *rest ] )
26
+ end
27
+ return results
28
+ end
29
+
30
+ # This is the end of the line, megatron.
31
+ return [ object[ key ] ].compact if rest.empty?
32
+
33
+ # Traverse hashes and arrays
34
+ case object[ key ]
35
+ when Hash
36
+ return _find( object[ key ], rest )
37
+ when Array
38
+ object[ key ].each do |obj|
39
+ results += _find( obj, rest )
40
+ end
41
+ end
42
+
43
+ return results
44
+ end
45
+
46
+ end
@@ -0,0 +1,3 @@
1
+ module Traipse
2
+ VERSION = "0.5.0"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'traipse'
5
+
6
+ RSpec.configure do |config|
7
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ data = {
4
+ "name" => "Percival",
5
+ "board" => {
6
+ "name" => "cats"
7
+ },
8
+ "categories" => [
9
+ { "name" => "animals" },
10
+ { "name" => "kitties" },
11
+ { "name" => "robots" },
12
+ ],
13
+ "products" => [
14
+ "shoes" => {
15
+ "brands" => [
16
+ { "name" => "converse" },
17
+ { "name" => "adidas" },
18
+ { "name" => "nike" }
19
+ ]
20
+ },
21
+ "apparel" => {
22
+ "brands" => [
23
+ { "name" => "Calvin Klein" },
24
+ { "name" => "Diesel" },
25
+ { "name" => "Betsey Johnson" },
26
+ { "name" => [ "Marc", "Ecko" ] },
27
+ { "caltrops" => 'Yes Please' }
28
+ ]
29
+ }
30
+ ]
31
+ };
32
+
33
+ describe Traipse do
34
+
35
+ it "can find top level values" do
36
+ Traipse.find( data, 'name' ).should == [ 'Percival' ]
37
+ end
38
+
39
+ it "can get to nested values" do
40
+ Traipse.find( data, 'board.name' ).should == [ 'cats' ]
41
+ end
42
+
43
+ it "can traverse arrays" do
44
+ Traipse.find( data, 'categories.name' ).should == [ "animals", "kitties", "robots" ]
45
+ end
46
+
47
+ it "can traverse arrays to get to nested values" do
48
+ Traipse.find( data, 'products.shoes.brands.name' ).should ==
49
+ [ "converse", "adidas", "nike" ]
50
+ end
51
+
52
+ it "can handle key wildcards" do
53
+ Traipse.find( data, 'products.*.brands.name' ).should ==
54
+ [ "converse", "adidas", "nike", "Calvin Klein",
55
+ "Diesel", "Betsey Johnson", [ "Marc", "Ecko" ] ]
56
+
57
+ Traipse.find( data, '*.name' ).should == [ "cats", "animals", "kitties", "robots" ]
58
+ end
59
+
60
+ it "can do multiple wildcards" do
61
+ Traipse.find( data, "products.*.brands.*" ).should ==
62
+ [ "converse", "adidas", "nike", "Calvin Klein",
63
+ "Diesel", "Betsey Johnson", [ "Marc", "Ecko" ], 'Yes Please' ]
64
+ end
65
+
66
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "traipse/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "traipse"
7
+ s.version = Traipse::VERSION
8
+ s.authors = ["Pawel Szymczykowski"]
9
+ s.email = ["makenai@gmail.com"]
10
+ s.homepage = "https://github.com/makenai/traipse"
11
+ s.summary = %q{Traverse data structures with a dot notated string.}
12
+ s.description = %q{Traipse is a library that allows you to address a data structure of Hashes & Arrays using a dot notated string & wildcards. ex: 'categories.*.name'. Like X-Path but dumber.}
13
+
14
+ s.rubyforge_project = "traipse"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: traipse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pawel Szymczykowski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-25 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: ! 'Traipse is a library that allows you to address a data structure of
15
+ Hashes & Arrays using a dot notated string & wildcards. ex: ''categories.*.name''.
16
+ Like X-Path but dumber.'
17
+ email:
18
+ - makenai@gmail.com
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - .gitignore
24
+ - Gemfile
25
+ - README.rdoc
26
+ - Rakefile
27
+ - lib/traipse.rb
28
+ - lib/traipse/version.rb
29
+ - spec/spec_helper.rb
30
+ - spec/traipse_spec.rb
31
+ - traipse.gemspec
32
+ homepage: https://github.com/makenai/traipse
33
+ licenses: []
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project: traipse
52
+ rubygems_version: 1.8.17
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: Traverse data structures with a dot notated string.
56
+ test_files:
57
+ - spec/spec_helper.rb
58
+ - spec/traipse_spec.rb