Files
mruby-mruby/mrbgems/mruby-set
Yukihiro "Matz" Matsumoto 0fab703028 class.c: use linear search for method tables; make ROM entries const
Replace binary search with linear scan in mt_get(), mt_put(),
mt_del(), mt_chain_has(), and mrb_mt_foreach(). The method cache
makes repeated lookups O(1), so linear scan on cache misses is
acceptable.

This removes the sorting requirement, allowing ROM entry arrays
to be declared const. On embedded systems, const static data
resides in flash/ROM instead of RAM, saving ~8.4KB for ~700
method entries on 32-bit MCUs.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 08:26:05 +09:00
..
2022-10-22 08:31:38 +10:00
2025-10-08 23:55:22 +09:00

mruby-set

mruby-set provides a Set class for mruby, offering a collection of unordered, unique elements. It's useful when you need to store a group of items and quickly check for membership, or perform set operations like union, intersection, and difference.

Installation

To use mruby-set in your mruby project, add the following to your build_config.rb:

conf.gem "#{MRUBY_ROOT}/mrbgems/mruby-set"

Or, if you have it as a separate gem:

conf.gem :github => "mruby/mruby-set"

Usage and Examples

Creating a Set

You can create a set from an array or by using the Set.[] shorthand:

require 'set' # Not strictly necessary in mruby if compiled in

set1 = Set.new([1, 2, 3])
#=> Set[1, 2, 3]

set2 = Set[3, 4, 5]
#=> Set[3, 4, 5]

Adding and Deleting Elements

s = Set.new
s.add(10)    #=> Set[10]
s << 20      #=> Set[10, 20]
s.add?(30)   #=> Set[10, 20, 30]
s.add?(20)   #=> nil (20 is already in the set)

s.delete(10) #=> Set[20, 30]
s.delete?(5) #=> nil (5 was not in the set)
s.delete?(20) #=> Set[30]

Set Operations

mruby-set supports common set operations:

Union (|, +, union): Returns a new set containing all elements from both sets.

set_a = Set[1, 2, 3]
set_b = Set[3, 4, 5]

set_a | set_b  #=> Set[1, 2, 3, 4, 5]
set_a + set_b  #=> Set[1, 2, 3, 4, 5]

Intersection (&, intersection): Returns a new set containing elements common to both sets.

set_a = Set[1, 2, 3]
set_b = Set[3, 4, 5]

set_a & set_b  #=> Set[3]

Difference (-, difference): Returns a new set containing elements from the first set that are not in the second set.

set_a = Set[1, 2, 3]
set_b = Set[3, 4, 5]

set_a - set_b  #=> Set[1, 2]

Exclusive OR (^): Returns a new set containing elements that are in one or the other of the sets, but not in both.

set_a = Set[1, 2, 3]
set_b = Set[3, 4, 5]

set_a ^ set_b  #=> Set[1, 2, 4, 5]

Querying the Set

Checking for inclusion (include?, member?, ===):

s = Set["apple", "banana", "cherry"]
s.include?("banana")  #=> true
s.member?("grape")    #=> false

Checking size (size, length):

s = Set[10, 20, 30]
s.size #=> 3

Checking if empty (empty?):

Set.new.empty? #=> true
Set[1].empty?  #=> false

Subset and Superset (subset?, superset?, <, <=, >, >=):

set_main = Set[1, 2, 3, 4]
sub = Set[2, 3]
super_set = Set[1, 2, 3, 4, 5]

sub.subset?(set_main)         #=> true
set_main.superset?(sub)       #=> true
set_main < super_set          #=> true (proper subset)
super_set > set_main          #=> true (proper superset)
Set[1,2].proper_subset?(Set[1,2,3]) #=> true
Set[1,2,3].proper_superset?(Set[1,2]) #=> true

Disjoint (disjoint?): Returns true if the set has no elements in common with the given set.

Set[1, 2].disjoint?(Set[3, 4]) #=> true
Set[1, 2].disjoint?(Set[2, 3]) #=> false

Intersect (intersect?): Returns true if the set has any elements in common with the given set.

Set[1, 2].intersect?(Set[2, 3]) #=> true
Set[1, 2].intersect?(Set[3, 4]) #=> false

Other Useful Methods

Convert to Array (to_a):

s = Set["a", "b", "c"]
s.to_a #=> ["a", "b", "c"] (order may vary)

Iterating (each):

s = Set[1, 2, 3]
s.each { |x| puts x * 10 }
# Output:
# 10
# 20
# 30

Map/Collect (map!, collect!): Modifies the set by applying the block to each element.

s = Set[1, 2, 3]
s.map! { |x| x * x } #=> Set[1, 4, 9]

Select/Filter (select!, filter!): Keeps elements for which the block returns true.

s = Set[1, 2, 3, 4, 5]
s.select! { |x| x.even? } #=> Set[2, 4]

Reject (reject!): Deletes elements for which the block returns true.

s = Set[1, 2, 3, 4, 5]
s.reject! { |x| x.odd? } #=> Set[2, 4]

Clear (clear): Removes all elements from the set.

s = Set[1, 2, 3]
s.clear #=> Set[]

Replace (replace): Replaces the contents of the set with the contents of the given enumerable.

s = Set[1, 2, 3]
s.replace([4, 5]) #=> Set[4, 5]

Flatten (flatten, flatten!): Returns a new set that is a copy of the set, flattening any nested sets. flatten! modifies the set in place.

s = Set[1, Set[2, 3], 4]
s.flatten #=> Set[1, 2, 3, 4]

Method Overview

Here's a list of commonly used methods available in mruby-set:

  • Set.[](*ary)
  • initialize(enum = nil, &block)
  • size, length
  • empty?
  • clear
  • replace(enum)
  • to_a
  • include?(o), member?(o), ===
  • superset?(set), >=
  • proper_superset?(set), >
  • subset?(set), <=
  • proper_subset?(set), <
  • intersect?(set)
  • disjoint?(set)
  • each(&block)
  • add(o), <<(o)
  • add?(o)
  • delete(o)
  • delete?(o)
  • delete_if { |o| ... }
  • keep_if { |o| ... }
  • collect! { |o| ... }, map! { |o| ... }
  • reject! { |o| ... }
  • select! { |o| ... }, filter! { |o| ... }
  • merge(enum)
  • subtract(enum)
  • |(enum), +(enum), union(enum)
  • -(enum), difference(enum)
  • &(enum), intersection(enum)
  • ^(enum)
  • ==(other)
  • hash
  • eql?(o)
  • classify { |o| ... }
  • divide(&func)
  • join(separator = nil)
  • inspect, to_s
  • flatten, flatten!

Limitations

These methods are not implemented yet:

  • freeze
  • to_set
  • divide(Set#divide with 2 arity block is not implemented.)

License

Under the MIT License: