Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/evolve75/rubytree

A General Purpose Tree Data Structure for Ruby
https://github.com/evolve75/rubytree

data-structures rt-gem ruby traversal tree

Last synced: about 12 hours ago
JSON representation

A General Purpose Tree Data Structure for Ruby

Awesome Lists containing this project

README

        

# **RubyTree** #

[![Gem Version](https://badge.fury.io/rb/rubytree.png)](http://badge.fury.io/rb/rubytree)
![Build State](https://github.com/evolve75/rubytree/actions/workflows/ruby.yml/badge.svg)
[![Code Climate](https://codeclimate.com/github/evolve75/RubyTree.png)](https://codeclimate.com/github/evolve75/RubyTree)
[![Coverage Status](https://coveralls.io/repos/evolve75/RubyTree/badge.png)](https://coveralls.io/r/evolve75/RubyTree)

__ _ _
/__\_ _| |__ _ _| |_ _ __ ___ ___
/ \// | | | '_ \| | | | __| '__/ _ \/ _ \
/ _ \ |_| | |_) | |_| | |_| | | __/ __/
\/ \_/\__,_|_.__/ \__, |\__|_| \___|\___|
|___/

## DESCRIPTION: ##

**RubyTree** is a pure Ruby implementation of the generic
[tree data structure][tree_data_structure]. It provides a node-based model to
store named nodes in the tree, and provides simple APIs to access, modify and
traverse the structure.

The implementation is *node-centric*, where individual nodes in the tree are the
primary structural elements. All common tree-traversal methods ([pre-order][],
[post-order][], and [breadth-first][]) are supported.

The library mixes in the [Enumerable][] and [Comparable][] modules to allow
access to the tree as a standard collection (iteration, comparison, etc.).

A [Binary tree][] is also provided, which provides the [in-order][] traversal in
addition to the other methods.

**RubyTree** supports importing from, and exporting to [JSON][], and also
supports the Ruby's standard object [marshaling][].

This is a [BSD licensed][BSD] open source project, and is hosted at
[github.com/evolve75/RubyTree][rt@github], and is available as a standard gem
from [rubygems.org/gems/rubytree][rt_gem].

The home page for **RubyTree** is at [rubytree.anupamsg.me][rt_site].

## WHAT'S NEW: ##

See [History](./History.md) for the detailed Changelog.

See [API-CHANGES](./API-CHANGES.md) for the detailed description of
API level changes.

## GETTING STARTED: ##

This is a basic usage example of the library to create and manipulate a tree.
See the [API][rt_doc] documentation for more details.

```ruby
#!/usr/bin/env ruby
#
# example_basic.rb:: Basic usage of the tree library.
#
# Copyright (C) 2013-2022 Anupam Sengupta
#
# The following example implements this tree structure:
#
# +------------+
# | ROOT |
# +-----+------+
# +-------------+------------+
# | |
# +-------+-------+ +-------+-------+
# | CHILD 1 | | CHILD 2 |
# +-------+-------+ +---------------+
# |
# |
# +-------+-------+
# | GRANDCHILD 1 |
# +---------------+

# ..... Example starts.
require 'tree' # Load the library

# ..... Create the root node first.
# ..... Note that every node has a name and an optional content payload.
root_node = Tree::TreeNode.new("ROOT", "Root Content")
root_node.print_tree

# ..... Now insert the child nodes.
# Note that you can "chain" the child insertions to any depth.
root_node << Tree::TreeNode.new("CHILD1", "Child1 Content") << Tree::TreeNode.new("GRANDCHILD1", "GrandChild1 Content")
root_node << Tree::TreeNode.new("CHILD2", "Child2 Content")

# ..... Lets print the representation to stdout.
# ..... This is primarily used for debugging purposes.
root_node.print_tree

# ..... Lets directly access children and grandchildren of the root.
# ..... The can be "chained" for a given path to any depth.
child1 = root_node["CHILD1"]
grand_child1 = root_node["CHILD1"]["GRANDCHILD1"]

# ..... Now retrieve siblings of the current node as an array.
siblings_of_child1 = child1.siblings

# ..... Retrieve immediate children of the root node as an array.
children_of_root = root_node.children

# ..... Retrieve the parent of a node.
parent = child1.parent

# ..... This is a depth-first and L-to-R pre-ordered traversal.
root_node.each { |node| node.content.reverse }

# ..... Remove a child node from the root node.
root_node.remove!(child1)

# .... Many more methods are available. Check out the documentation!
```

This example can also be found at
[examples/example_basic.rb](examples/example_basic.rb).

## REQUIREMENTS: ##

* [Ruby][] 2.7.x and above.

* Run-time Dependencies:

* [JSON][] for converting to/from the JSON format

* Development dependencies (not required for installing the gem):

* [Bundler][] for creating the stable build environment
* [Rake][] for building the package
* [Yard][] for the documentation
* [RSpec][] for additional Ruby Spec test files
* [Rubocop][] for linting the code

## INSTALL: ##

To install the [gem][rt_gem], run this command from a terminal/shell:

$ gem install rubytree

This should install the gem file for **RubyTree**. Note that you might need to
have super-user privileges (root/sudo) to successfully install the gem.

## DOCUMENTATION: ##

The primary class **RubyTree** is [Tree::TreeNode][TreeNode]. See the class
documentation for an example of using the library.

If the *ri* documentation was generated during install, you can use this
command at the terminal to view the text mode ri documentation:

$ ri Tree::TreeNode

Documentation for the latest released version is available at:

[rubytree.anupamsg.me/rdoc][rt_doc]

Documentation for the latest git HEAD is available at:

[rdoc.info/projects/evolve75/RubyTree][rt_doc@head]

Note that the documentation is formatted using [Yard][].

## DEVELOPERS: ##

This section is only for modifying **RubyTree** itself. It is not required for
using the library!

You can download the latest released source code as a tar or zip file, as
mentioned above in the installation section.

Alternatively, you can checkout the latest commit/revision from the Version
Control System. Note that **RubyTree**'s primary [SCM][] is [git][] and is
hosted on [github.com][rt@github].

### Using the git Repository ###

The git repository is available at [github.com/evolve75/RubyTree][rt@github].

For cloning the git repository, use one of the following commands:

$ git clone git://github.com/evolve75/RubyTree.git # using ssh

or

$ git clone https://github.com/evolve75/RubyTree.git # using https

### Setting up the Development Environment ###

**RubyTree** uses [Bundler][] to manage its dependencies. This allows for a
simplified dependency management, for both run-time as well as during build.

After checking out the source, run:

$ gem install bundler
$ bundle install
$ bundle exec rake test:all
$ bundle exec rake doc:yard
$ bundle exec rake gem:package

These steps will install any missing dependencies, run the tests/specs,
generate the documentation, and finally generate the gem file.

Note that the documentation uses [Yard][], which will be
downloaded and installed automatically by [Bundler][].

## ACKNOWLEDGMENTS: ##

A big thanks to the following contributors for helping improve **RubyTree**:

1. Dirk Breuer for contributing the JSON conversion code.
2. Vincenzo Farruggia for contributing the (sub)tree cloning code.
3. [Eric Cline](https://github.com/escline) for the Rails JSON encoding fix.
4. [Darren Oakley](https://github.com/dazoakley) for the tree merge methods.
5. [Youssef Rebahi-Gilbert](https://github.com/ysf) for the code to check
duplicate node names in the tree (globally unique names).
6. [Paul de Courcel](https://github.com/pdecourcel) for adding the
`postordered_each` method.
7. [Jen Hamon](http://www.github.com/jhamon) for adding the `from_hash` method.
8. [Evan Sharp](https://github.com/packetmonkey) for adding the `rename` and
`rename_child` methods.
9. [Aidan Steele](https://github.com/aidansteele) for performance improvements
to `is_root?` and `node_depth`.
10. [Marco Ziccadi](https://github.com/MZic) for adding the `path_as_string` and
`path_as_array` methods.
11. [John Mortlock](https://github.com/jmortlock) for significant modernization
of the library code and addition of Github `workflows`.
12. [Hermann Mayer](https://github.com/jack12816) for adding support for
specialized tree nodes (sub-classes of `Tree::TreeNode`).
13. [Jakub Pavlik](https://github.com/igneus) for fixing the creation of
detached copies of unclonable objects such as `:symbol`, `true|false`, etc.
14. [bghalami-rc](https://github.com/bghalami-rc) for updating the guard clause
in the `from_hash` method.

## LICENSE: ##

**RubyTree** is licensed under the terms of the [BSD][] license. See
[LICENSE.md](./LICENSE.md) for details.

[BSD]: http://opensource.org/licenses/bsd-license.php "BSD License"
[Binary tree]: http://en.wikipedia.org/wiki/Binary_tree "Binary Tree Data Structure"
[Bundler]: http://bundler.io "Bundler"
[Comparable]: http://ruby-doc.org/core/Comparable.html "Comparable mix-in"
[Enumerable]: http://ruby-doc.org/core/Enumerable.html "Enumerable mix-in"
[JSON]: https://rubygems.org/gems/json "JSON"
[Rake]: https://rubygems.org/gems/rake "Rake"
[Ruby]: http://www.ruby-lang.org "Ruby Programming Language"
[SCM]: http://en.wikipedia.org/wiki/Source_Code_Management "Source Code Management"
[Yard]: http://yardoc.org "Yard Document Generator"
[breadth-first]: http://en.wikipedia.org/wiki/Breadth-first_search "Breadth-first (level-first) Traversal"
[git]: http://git-scm.com "Git SCM"
[in-order]: http://en.wikipedia.org/wiki/Tree_traversal#In-order "In-order (symmetric) Traversal"
[marshaling]: http://ruby-doc.org/core/Marshal.html "Marshaling in Ruby"
[post-order]: http://en.wikipedia.org/wiki/Tree_traversal#Post-order "Post-ordered Traversal"
[pre-order]: http://en.wikipedia.org/wiki/Tree_traversal#Pre-order "Pre-ordered Traversal"
[rt@github]: http://github.com/evolve75/RubyTree "RubyTree Project Page on Github"
[rt_doc@head]: http://rdoc.info/projects/evolve75/RubyTree "RubyTree Documentation for VCS Head"
[rt_doc]: http://rubytree.anupamsg.me/rdoc "RubyTree Documentation"
[rt_gem]: http://rubygems.org/gems/rubytree "RubyTree Gem"
[rt_site]: http://rubytree.anupamsg.me "RubyTree Site"
[tree_data_structure]: http://en.wikipedia.org/wiki/Tree_data_structure "Tree Data Structure"
[RSpec]: https://relishapp.com/rspec/
[Rubocop]: https://rubocop.org/

[TreeNode]: rdoc-ref:Tree::TreeNode