multiset 0.3.0
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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/lib/multiset.rb +133 -0
- data/lib/multiset/libmultimap.rb +475 -0
- data/lib/multiset/libmultiset.rb +757 -0
- data/multiset.gemspec +66 -0
- data/spec/multiset_spec.rb +12 -0
- data/spec/multiset_spec_ported.rb +528 -0
- data/spec/spec_helper.rb +12 -0
- metadata +144 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", ">= 2.3.0"
|
10
|
+
gem "bundler", ">= 1.0.0"
|
11
|
+
gem "jeweler", ">= 1.5.2"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 maraigue
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= multiset
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to multiset
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2011 maraigue. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "multiset"
|
16
|
+
gem.homepage = "http://github.com/maraigue/multiset"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Multiset library for Ruby}
|
19
|
+
gem.description = %Q{Ruby implementation of multiset. Unlike ordinary set(see Ruby documentation for "set" library), multiset can contain two or more same items.}
|
20
|
+
gem.email = "main@hhiro.net"
|
21
|
+
gem.authors = ["H.Hiro(Maraigue)"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
45
|
+
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
47
|
+
rdoc.title = "multiset #{version}"
|
48
|
+
rdoc.rdoc_files.include('README*')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/lib/multiset.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
#Rubyによる多重集合(マルチセット)・多重連想配列(マルチマップ)の実装です。
|
2
|
+
#
|
3
|
+
#Ruby implementation of multiset and multimap.
|
4
|
+
#
|
5
|
+
#==インストール(Installation)
|
6
|
+
#
|
7
|
+
#インストールはsetup.rbによって行われます。詳しくはINSTALL.ja.txtをご覧下さい。
|
8
|
+
#
|
9
|
+
#setup.rb performs installation. See INSTALL.en.txt for more information.
|
10
|
+
#
|
11
|
+
#==更新履歴(Revision history)
|
12
|
+
#
|
13
|
+
#* Version 0.10(2008/2/9)
|
14
|
+
# * 公開開始。
|
15
|
+
#* Version 0.11(2008/2/12)
|
16
|
+
# * Multiset#&の実装が誤っていたのを修正。
|
17
|
+
# * ドキュメントの間違いを修正。
|
18
|
+
#* Version 0.12(2008/2/16)
|
19
|
+
# * Hash#to_multisetに冗長な処理があったので修正。
|
20
|
+
# * Multisetにメソッドmap, map!, collect, collect!, map_with, map_with!を追加。
|
21
|
+
# * これに伴い、従来のMultiset#mapなどとは挙動が変更されました。
|
22
|
+
# (従来のMultiset#mapなどはEnumerable#mapを呼んでいたので、
|
23
|
+
# 返り値は配列でした。)
|
24
|
+
#* Version 0.13(2008/3/1)
|
25
|
+
# * setup.rb(http://i.loveruby.net/ja/projects/setup/)を用いたインストールに対応した。
|
26
|
+
#* Version 0.131(2008/3/2)
|
27
|
+
# * ドキュメントの間違いを修正。
|
28
|
+
#* Version 0.20(beta) (2008/3/23)
|
29
|
+
# * Multimapクラスを追加。またこれに伴い、Hash#to_multimap・Hash#multimap
|
30
|
+
# メソッドを追加。
|
31
|
+
# * Multiset.parse、Multiset.parse_force、Multiset.parse_string、
|
32
|
+
# Multiset.parse_string?メソッドを追加。
|
33
|
+
# * Multiset#==において、引数がMultisetのインスタンスでない場合、
|
34
|
+
# 強制的にfalseを返すようにした。
|
35
|
+
# * Multiset#subset?、Multiset#superset?、Multiset#proper_subset?、
|
36
|
+
# Multiset#proper_superset?において、引数がMultisetのインスタンスで
|
37
|
+
# ない場合、強制的にArgumentErrorを発生するようにした。
|
38
|
+
#* Version 0.201(beta) (2008/3/25)
|
39
|
+
# * Multiset#classify、Multiset#classify_withの返り値をMultimapにした。
|
40
|
+
# * Multimap#to_s、Multimap#inspectを追加。(ドキュメントは省略させていただきます)
|
41
|
+
# * Multiset#to_sの実装が誤っていたのを修正。
|
42
|
+
#* Version 0.202(beta) (2008/4/23)
|
43
|
+
# * GNU LGPLの文書を添付していなかったので追加。申し訳ありません。
|
44
|
+
#<em></em>
|
45
|
+
#* Version 0.10(2008/2/9)
|
46
|
+
# * First distribution.
|
47
|
+
#* Version 0.11(2008/2/12)
|
48
|
+
# * [Fixed] Wrong implementation of Multiset#&
|
49
|
+
# * [Fixed] Wrong documentation
|
50
|
+
#* Version 0.12(2008/2/16)
|
51
|
+
# * [Fixed] Removing redundant process in Hash#to_multiset
|
52
|
+
# * [Added] Methods: map, map!, collect, collect!, map_with, map_with! on Multiset
|
53
|
+
# * As a result, what Multiset#map and other methods do has changed.
|
54
|
+
# (As of version 0.11, Multiset#map returns an array, because
|
55
|
+
# Multiset#map means Enumerable#map.)
|
56
|
+
#* Version 0.13(2008/3/1)
|
57
|
+
# * Made setup.rb(http://i.loveruby.net/en/projects/setup/) be avaliable.
|
58
|
+
#* Version 0.131(2008/3/2)
|
59
|
+
# * [Fixed] Wrong documentation
|
60
|
+
#* Version 0.20(beta) (2008/3/23)
|
61
|
+
# * [Added] Multimap class, Hash#to_multimap, Hash#multimap
|
62
|
+
# * [Added] Multiset.parse, Multiset.parse_force, Multiset.parse_string, Multiset.parse_string?
|
63
|
+
# * [Changed] In Multiset#==, if the argument is not an instance of Multiset,
|
64
|
+
# Multiset#== always returns false.
|
65
|
+
# * [Changed] In Multiset#subset?, Multiset#superset?, Multiset#proper_subset?
|
66
|
+
# and Multiset#proper_superset?, if the argument is not an instance of Multiset,
|
67
|
+
# those methods always raise ArgumentError.
|
68
|
+
#* Version 0.201(beta) (2008/3/25)
|
69
|
+
# * [Changed] Multiset#classify, Multiset#classify_with returns a Multimap.
|
70
|
+
# * [Added] Multimap#to_s, Multimap#inspect (No document)
|
71
|
+
# * [Fixed] Wrong implementation of Multiset#to_s
|
72
|
+
#* Version 0.202(beta) (2008/4/23)
|
73
|
+
# * Added the text of GNU LGPL to the archive. I'm very sorry...
|
74
|
+
#
|
75
|
+
#==著作権表示(Copyright)
|
76
|
+
#
|
77
|
+
#Author:: Maraigue(http://f52.aaa.livedoor.jp/~maraigue/)
|
78
|
+
#Version:: 0.202(beta) (2008/4/23)
|
79
|
+
#Copyright:: (C)2008 Maraigue
|
80
|
+
#
|
81
|
+
#このプログラムはBSDライセンスにて提供する 無 保 証 のプログラムです。
|
82
|
+
#詳細はBSDLicense.txtをご覧下さい。
|
83
|
+
#
|
84
|
+
#日本語の参考訳は以下のURLにあります。
|
85
|
+
#http://sourceforge.jp/projects/opensource/wiki/licenses%2Fnew_BSD_license
|
86
|
+
#ただし、法的にはBSDLicense.txtに書かれた英語の文章のみが有効です。
|
87
|
+
#
|
88
|
+
#setup.rbはMinero Aoki氏(http://i.loveruby.net/)の制作です。
|
89
|
+
#setup.rbのみは、GNU LGPL(version 2.1)のライセンスが適用されます。
|
90
|
+
#GNU LGPLについてはGNU_LGPL.txtをご覧下さい。
|
91
|
+
#
|
92
|
+
#This program is distributed with ABSOLUTELY NO WARRANTY, under BSD License.
|
93
|
+
#See BSDLicense.txt for more detail.
|
94
|
+
#
|
95
|
+
#setup.rb is made by Minero Aoki(http://i.loveruby.net/).
|
96
|
+
#Only setup.rb is distributed under GNU LGPL(version 2.1).
|
97
|
+
#See GNU_LGPL.txt for more detail.
|
98
|
+
|
99
|
+
require 'multiset/libmultiset'
|
100
|
+
require 'multiset/libmultimap'
|
101
|
+
|
102
|
+
#--
|
103
|
+
# Sample
|
104
|
+
#++
|
105
|
+
if __FILE__ == $0
|
106
|
+
puts 'Creating multisets'
|
107
|
+
a = {1=>5, 4=>2, 6=>0}.to_multiset
|
108
|
+
b = Multiset[1,1,4,4,6,6]
|
109
|
+
p a
|
110
|
+
p b
|
111
|
+
|
112
|
+
puts 'Operations for multisets'
|
113
|
+
p a + b
|
114
|
+
p a - b
|
115
|
+
p a & b
|
116
|
+
p a | b
|
117
|
+
|
118
|
+
puts 'Modifying multisets'
|
119
|
+
p a.reject!{ |item| item == 3 }
|
120
|
+
p a
|
121
|
+
p a.reject!{ |item| item == 4 }
|
122
|
+
p a
|
123
|
+
a.add(3)
|
124
|
+
a.add(4, 10)
|
125
|
+
a << 1
|
126
|
+
p a
|
127
|
+
|
128
|
+
puts 'Flattening multisets'
|
129
|
+
a = Multiset[6,6,3,4,Multiset[5,8],Multiset[6,Multiset[3,8],8],8]
|
130
|
+
p a
|
131
|
+
p a.flatten!
|
132
|
+
p a.flatten!
|
133
|
+
end
|
@@ -0,0 +1,475 @@
|
|
1
|
+
#==概要(Basic information)
|
2
|
+
#
|
3
|
+
#Rubyによる多重連想配列(マルチマップ)の実装です。
|
4
|
+
#通常の連想配列(Rubyでは"Hash"クラス)と異なり、多重連想配列は
|
5
|
+
#1つのキーに対して複数の要素が存在し得ます。
|
6
|
+
#
|
7
|
+
#メソッド名は基本的にHashクラスに合わせてあります。またHashクラスが持つ
|
8
|
+
#メソッドの大部分を実装していますが、いくつか未実装なものもあります。
|
9
|
+
#
|
10
|
+
#Ruby implementation of multimap.
|
11
|
+
#Unlike ordinary map, also known as associative array
|
12
|
+
#(see Ruby documentation for "Hash" class),
|
13
|
+
#multimap can contain two or more items for a key.
|
14
|
+
#
|
15
|
+
#Most methods' names are same as those of Hash class, and all other than
|
16
|
+
#a few methods in Hash class is implemented on Multimap class.
|
17
|
+
|
18
|
+
class Multimap
|
19
|
+
include Enumerable
|
20
|
+
|
21
|
+
#--
|
22
|
+
# Constructors
|
23
|
+
#++
|
24
|
+
|
25
|
+
# 新しい多重連想配列を生成します。Hash#newと異なり、デフォルト値は
|
26
|
+
# 設定できません。
|
27
|
+
#
|
28
|
+
# Generates a new multimap. Different from Hash#new , you can not
|
29
|
+
# specify default value.
|
30
|
+
def initialize
|
31
|
+
@assoc = Hash.new{ |hash, key| hash[key] = Multiset.new }
|
32
|
+
end
|
33
|
+
|
34
|
+
# Removes all keys in @assoc if the value associated with key is
|
35
|
+
# empty multiset.
|
36
|
+
def cleanup # :nodoc:
|
37
|
+
@assoc.reject!{ |key, value_list| value_list.empty? }
|
38
|
+
end
|
39
|
+
private :cleanup
|
40
|
+
|
41
|
+
# キー<code>key</code>に対応する値(複数存在しうる)を、
|
42
|
+
# Multisetとして返します。Hash#fetchの場合と異なり、キーに対応する
|
43
|
+
# 値が存在しない場合の扱いを指定することはできません。
|
44
|
+
# (そのような場合、空のMultisetが返ります。)
|
45
|
+
#
|
46
|
+
# Returns values associated with <code>key</code> with format of
|
47
|
+
# Multiset. Different from Hash#fetch, you can not specify
|
48
|
+
# a value or a process when <code>key</code> has not associated with
|
49
|
+
# any value. If <code>key</code> has not associated with any value,
|
50
|
+
# Multimap#fetch returns empty Multiset.
|
51
|
+
def fetch(key)
|
52
|
+
@assoc[key]
|
53
|
+
end
|
54
|
+
alias :[] :fetch
|
55
|
+
|
56
|
+
# キー<code>key</code>に対応する値(複数存在しうる)を
|
57
|
+
# <code>value_list</code>で置き換えます。この際、
|
58
|
+
# <code>value_list</code>はMultiset.parseを用いてMultisetに変換されます。
|
59
|
+
#
|
60
|
+
# <code>value_list</code>を返します。
|
61
|
+
#
|
62
|
+
# Sets values associated with <code>key</code> to <code>value_list</code>.
|
63
|
+
# <code>value_list</code> is converted to a Multiset by Multiset.parse .
|
64
|
+
#
|
65
|
+
# Returns <code>value_list</code>.
|
66
|
+
def store(key, value_list)
|
67
|
+
if value_list.class == Multiset
|
68
|
+
@assoc[key] = value_list.dup
|
69
|
+
else
|
70
|
+
@assoc[key] = Multiset.parse(value_list)
|
71
|
+
end
|
72
|
+
value_list
|
73
|
+
end
|
74
|
+
alias :[]= :store
|
75
|
+
|
76
|
+
# <code>self</code>が<code>other</code>と等しいかどうかを返します。
|
77
|
+
#
|
78
|
+
# Returns whether <code>self</code> is equal to <code>other</code>.
|
79
|
+
def ==(other)
|
80
|
+
return false unless other.instance_of?(Multimap)
|
81
|
+
@assoc == other.to_hash
|
82
|
+
end
|
83
|
+
|
84
|
+
# <code>self</code>を<code>Hash</code>に変換して返します。
|
85
|
+
# 生成されるハッシュの構造については、Hash#to_multimapをご覧下さい。
|
86
|
+
# その際、返されるハッシュにおいて値はすべてMultimap型となります。
|
87
|
+
#
|
88
|
+
# Converts <code>self</code> to a <code>Hash</code>.
|
89
|
+
# See Hash#to_multimap about format of generated hash.
|
90
|
+
# All values in the returned hash are multimaps.
|
91
|
+
def to_hash
|
92
|
+
@assoc.dup
|
93
|
+
end
|
94
|
+
|
95
|
+
# <code>self</code>に格納された要素をすべて削除します。
|
96
|
+
# <code>self</code>を返します。
|
97
|
+
#
|
98
|
+
# Removes all elements stored in <code>self</code>.
|
99
|
+
# Returns <code>self</code>.
|
100
|
+
def clear
|
101
|
+
@assoc.clear
|
102
|
+
end
|
103
|
+
|
104
|
+
# <code>self</code>の複製を生成して返します。
|
105
|
+
#
|
106
|
+
# Returns duplicated <code>self</code>.
|
107
|
+
def dup
|
108
|
+
@assoc.to_multimap
|
109
|
+
end
|
110
|
+
|
111
|
+
# <code>self</code>の内容を<code>other</code>のものに置き換えます。
|
112
|
+
# <code>self</code>を返します。
|
113
|
+
#
|
114
|
+
# Replaces <code>self</code> by <code>other</code>.
|
115
|
+
# Returns <code>self</code>.
|
116
|
+
def replace(other)
|
117
|
+
@assoc.clear
|
118
|
+
other.each_pair_with do |key, a_value, count|
|
119
|
+
@assoc[key].add a_value, count
|
120
|
+
end
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
# <code>key</code>に割り当てられた全ての値を削除し、その値を
|
125
|
+
# Multisetとして返します。
|
126
|
+
#
|
127
|
+
# Deletes all values associated with <code>key</code>, and returns
|
128
|
+
# those values as a Multiset.
|
129
|
+
def delete(key)
|
130
|
+
ret = @assoc[key]
|
131
|
+
@assoc.delete(key)
|
132
|
+
ret
|
133
|
+
end
|
134
|
+
|
135
|
+
# delete_ifと同じですが、<code>self</code>自身からはキーと値の組を
|
136
|
+
# 削除せず、要素が削除された結果の多重連想配列を新たに生成して
|
137
|
+
# 返します。
|
138
|
+
#
|
139
|
+
# Same as delete_if, but generates a new Multimap whose pairs of
|
140
|
+
# key and value are deleted, instead of deleting pairs in
|
141
|
+
# <code>self</code>.
|
142
|
+
def reject(&block) # :yields: key, single_value
|
143
|
+
ret = self.dup
|
144
|
+
ret.delete_if &block
|
145
|
+
ret
|
146
|
+
end
|
147
|
+
|
148
|
+
# ブロックに<code>self</code>のキーと値の組(値は1つ)を順次与え、
|
149
|
+
# 結果が真であった組をすべて削除します。
|
150
|
+
# <code>self</code>を返します。
|
151
|
+
#
|
152
|
+
# Gives all pairs of a key and single value in <code>self</code>
|
153
|
+
# to given block, and deletes that element if the block returns true.
|
154
|
+
# Returns <code>self</code>.
|
155
|
+
def delete_if(&block) # :yields: key, single_value
|
156
|
+
cleanup
|
157
|
+
@assoc.each_pair do |key, value_list|
|
158
|
+
value_list.delete_if{ |single_value|
|
159
|
+
block.call(key, single_value)
|
160
|
+
}
|
161
|
+
end
|
162
|
+
self
|
163
|
+
end
|
164
|
+
|
165
|
+
# delete_ifと同じですが、キーと値の組が1つも削除されなければ
|
166
|
+
# <code>nil</code>を返します。
|
167
|
+
#
|
168
|
+
# Same as delete_if, but returns <code>nil</code> if no pair of
|
169
|
+
# key and value is deleted.
|
170
|
+
def reject!(&block) # :yields: key, single_value
|
171
|
+
cleanup
|
172
|
+
ret = nil
|
173
|
+
@assoc.each_pair do |key, value_list|
|
174
|
+
ret = self if value_list.reject!{ |single_value|
|
175
|
+
block.call(key, single_value)
|
176
|
+
}
|
177
|
+
end
|
178
|
+
ret
|
179
|
+
end
|
180
|
+
|
181
|
+
# rejectと同じですが、ブロックへの引数が(キー、キーに割り当てられた値、
|
182
|
+
# その値がキーに割り当てられている個数)の3つの組で与えられます。
|
183
|
+
#
|
184
|
+
# Same as reject, but arguments given to block is the tuple of three:
|
185
|
+
# (key, one value associated with the key, numbers of that value
|
186
|
+
# associated with the key).
|
187
|
+
def reject_with(&block) # :yields: key, a_value, count
|
188
|
+
ret = self.dup
|
189
|
+
ret.delete_with &block
|
190
|
+
ret
|
191
|
+
end
|
192
|
+
|
193
|
+
# delete_ifと同じですが、ブロックへの引数が(キー、キーに割り当てられた値、
|
194
|
+
# その値がキーに割り当てられている個数)の3つの組で与えられます。
|
195
|
+
#
|
196
|
+
# Same as delete_if, but arguments given to block is the tuple of three:
|
197
|
+
# (key, one value associated with the key, numbers of that value
|
198
|
+
# associated with the key).
|
199
|
+
def delete_with(&block) # :yields: key, a_value, count
|
200
|
+
cleanup
|
201
|
+
@assoc.each_pair do |key, value_list|
|
202
|
+
value_list.delete_with{ |a_value, count|
|
203
|
+
block.call(key, a_value, count)
|
204
|
+
}
|
205
|
+
end
|
206
|
+
self
|
207
|
+
end
|
208
|
+
|
209
|
+
# <code>self</code>のすべてのキーと値の組について繰り返します。
|
210
|
+
# <code>self</code>を返します。
|
211
|
+
#
|
212
|
+
# Iterates for each pair of a key and a value in <code>self</code>.
|
213
|
+
# Returns <code>self</code>.
|
214
|
+
def each_pair
|
215
|
+
cleanup
|
216
|
+
@assoc.each_pair do |key, value_list|
|
217
|
+
value_list.each do |single_value|
|
218
|
+
yield key, single_value
|
219
|
+
end
|
220
|
+
end
|
221
|
+
self
|
222
|
+
end
|
223
|
+
alias :each :each_pair
|
224
|
+
|
225
|
+
# <code>self</code>のすべてのキーと値の組について、
|
226
|
+
# ブロックに(キー、キーに割り当てられた値、その値が割り当てられた数)
|
227
|
+
# の組を与えながら繰り返します。<code>self</code>を返します。
|
228
|
+
#
|
229
|
+
# Iterates for each pair of a key and a value in <code>self</code>,
|
230
|
+
# giving the tuple of three to block:
|
231
|
+
# (key, one value associated with the key, numbers of that value
|
232
|
+
# associated with the key). Returns <code>self</code>.
|
233
|
+
def each_pair_with
|
234
|
+
cleanup
|
235
|
+
@assoc.each_pair do |key, value_list|
|
236
|
+
value_list.each_pair do |a_value, count|
|
237
|
+
yield key, a_value, count
|
238
|
+
end
|
239
|
+
end
|
240
|
+
self
|
241
|
+
end
|
242
|
+
|
243
|
+
# <code>self</code>のすべてのキーと、そのキーに割り当てられた
|
244
|
+
# すべての値(Multisetで与えられる)の組について繰り返します。
|
245
|
+
# <code>self</code>を返します。
|
246
|
+
#
|
247
|
+
# Iterates for each pair of a key and all values associated with the key
|
248
|
+
# (list of values is given as Multiset) in <code>self</code>.
|
249
|
+
# Returns <code>self</code>.
|
250
|
+
def each_pair_list(&block) # :yields: key, value_list
|
251
|
+
cleanup
|
252
|
+
@assoc.each_pair &block
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
# <code>self</code>のすべてのキーについて繰り返します。
|
257
|
+
# <code>self</code>を返します。
|
258
|
+
#
|
259
|
+
# Iterates for each key in <code>self</code>. Returns <code>self</code>.
|
260
|
+
def each_key(&block) # :yields: key
|
261
|
+
cleanup
|
262
|
+
@assoc.each_key &block
|
263
|
+
end
|
264
|
+
|
265
|
+
# <code>self</code>のすべての値について繰り返します。
|
266
|
+
# <code>self</code>を返します。
|
267
|
+
#
|
268
|
+
# Iterates for each value in <code>self</code>. Returns <code>self</code>.
|
269
|
+
def each_value(&block) # :yields: single_value
|
270
|
+
cleanup
|
271
|
+
@assoc.each_value do |value_list|
|
272
|
+
value_list.each &block
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
# <code>self</code>のすべてのキーを、配列として返します。
|
277
|
+
#
|
278
|
+
# Returns an array in which keys in <code>self</code> are stored.
|
279
|
+
def keys
|
280
|
+
cleanup
|
281
|
+
@assoc.keys
|
282
|
+
end
|
283
|
+
|
284
|
+
|
285
|
+
# <code>self</code>のすべての値を、Multisetとして返します。
|
286
|
+
#
|
287
|
+
# Returns a Multiset in which values in <code>self</code> are stored.
|
288
|
+
def values
|
289
|
+
cleanup
|
290
|
+
ret = Multiset.new
|
291
|
+
@assoc.each_value do |value_list|
|
292
|
+
ret.merge! value_list
|
293
|
+
end
|
294
|
+
ret
|
295
|
+
end
|
296
|
+
|
297
|
+
# <code>self</code>に要素がないかどうかを返します。
|
298
|
+
#
|
299
|
+
# Returns whether <code>self</code> has no element.
|
300
|
+
def empty?
|
301
|
+
cleanup
|
302
|
+
@assoc.empty?
|
303
|
+
end
|
304
|
+
|
305
|
+
# <code>self</code>にキー<code>key</code>かあるかどうかを返します。
|
306
|
+
#
|
307
|
+
# Returns whether <code>self</code> has a key <code>key</code>.
|
308
|
+
def has_key?(key)
|
309
|
+
cleanup
|
310
|
+
@assoc.has_key?(key)
|
311
|
+
end
|
312
|
+
alias :key? :has_key?
|
313
|
+
alias :include? :has_key?
|
314
|
+
alias :member? :has_key?
|
315
|
+
|
316
|
+
# <code>self</code>に値<code>value</code>かあるかどうかを返します。
|
317
|
+
#
|
318
|
+
# Returns whether <code>self</code> has a value <code>value</code>.
|
319
|
+
def has_value?(value)
|
320
|
+
self.values.items.include?(value)
|
321
|
+
end
|
322
|
+
alias :value? :has_value?
|
323
|
+
|
324
|
+
# <code>self</code>から値が<code>value</code>であるような要素を
|
325
|
+
# 検索し、それに対応するキーを返します。該当するキーが複数存在する場合、
|
326
|
+
# そのうちの1つを返します。該当するキーが存在しなければ
|
327
|
+
# <code>nil</code>を返します。
|
328
|
+
#
|
329
|
+
# Search a pair of key and value from <code>self</code> such that
|
330
|
+
# the value is equal to the argument <code>value</code>.
|
331
|
+
# If two or keys are matched, returns one of them.
|
332
|
+
# If no key is matched, returns nil.
|
333
|
+
def key(value)
|
334
|
+
self.each_pair_with do |key, a_value, count|
|
335
|
+
return key if value == a_value
|
336
|
+
end
|
337
|
+
nil
|
338
|
+
end
|
339
|
+
alias :index :key
|
340
|
+
|
341
|
+
# <code>self</code>から<code>key_list</code>の各キーに対応する値
|
342
|
+
# (Multiset型)を取り出し、それらを配列として返します。
|
343
|
+
# すなわち、Multisetを要素とする配列を返します。
|
344
|
+
#
|
345
|
+
# Gets values (instances of Multiset) of <code>self</code>
|
346
|
+
# associated with <code>key_list</code>, and returns those values
|
347
|
+
# as an array. i.e. returns an array whose elements are multisets.
|
348
|
+
def values_at(*key_list)
|
349
|
+
key_list.map{ |key| self[key] }
|
350
|
+
end
|
351
|
+
alias :indexes :values_at
|
352
|
+
alias :indices :values_at
|
353
|
+
|
354
|
+
# <code>self</code>のキーと値を入れ替えたMultimapを返します。
|
355
|
+
# 例えばキー:aに対応する値が2つの:xと1つの:yであれば、変換結果は
|
356
|
+
# キー:xに:aが2つ、キー:yに:aが1つ対応するMultimapです。
|
357
|
+
#
|
358
|
+
# Returns a Multimap whose keys are values in <code>self</code>, and
|
359
|
+
# values are keys in <code>self</code>. For example,
|
360
|
+
# If <code>self</code> has a key :a associated with two :x and one :y,
|
361
|
+
# returned multimap has two keys :x and :y, and their values are
|
362
|
+
# two :a and one :a respectively.
|
363
|
+
def invert
|
364
|
+
ret = Multimap.new
|
365
|
+
self.each_pair_with do |key, a_value, count|
|
366
|
+
ret[a_value].add key, count
|
367
|
+
end
|
368
|
+
ret
|
369
|
+
end
|
370
|
+
|
371
|
+
# <code>self</code>に含まれている要素数を返します。
|
372
|
+
#
|
373
|
+
# Returns number of all elements in <code>self</code>.
|
374
|
+
def size
|
375
|
+
ret = 0
|
376
|
+
self.each_pair_with{ |key, a_value, count| ret += count }
|
377
|
+
ret
|
378
|
+
end
|
379
|
+
alias :length :size
|
380
|
+
|
381
|
+
# <code>self</code>に<code>other</code>の要素を追加します。
|
382
|
+
# <code>self</code>を返します。
|
383
|
+
#
|
384
|
+
# Add elements in <code>other</code> to <code>self</code>.
|
385
|
+
# Returns <code>self</code>.
|
386
|
+
def merge!(other)
|
387
|
+
other.each_pair_with do |key, a_value, count|
|
388
|
+
self[key].add a_value, count
|
389
|
+
end
|
390
|
+
self
|
391
|
+
end
|
392
|
+
|
393
|
+
# <code>self</code>と<code>other</code>の要素を合わせた多重集合を返します。
|
394
|
+
#
|
395
|
+
# Returns merged multiset of <code>self</code> and <code>other</code>.
|
396
|
+
def merge(other)
|
397
|
+
ret = self.dup
|
398
|
+
ret.merge! other
|
399
|
+
end
|
400
|
+
alias :+ :merge
|
401
|
+
|
402
|
+
def to_s(delim = "\n") # :nodoc:
|
403
|
+
cleanup
|
404
|
+
|
405
|
+
buf = ''
|
406
|
+
init = true
|
407
|
+
@assoc.each_pair do |key, value_list|
|
408
|
+
if init
|
409
|
+
init = false
|
410
|
+
else
|
411
|
+
buf += delim
|
412
|
+
end
|
413
|
+
buf += "#{key.inspect}=>{"
|
414
|
+
|
415
|
+
init_val = true
|
416
|
+
value_list.each_pair do |a_value, count|
|
417
|
+
if init_val
|
418
|
+
init_val = false
|
419
|
+
else
|
420
|
+
buf += ", "
|
421
|
+
end
|
422
|
+
buf += "\##{count} #{a_value.inspect}"
|
423
|
+
end
|
424
|
+
buf += "}"
|
425
|
+
end
|
426
|
+
buf
|
427
|
+
end
|
428
|
+
|
429
|
+
def inspect # :nodoc:
|
430
|
+
buf = "#<Multimap:"
|
431
|
+
buf += self.to_s(', ')
|
432
|
+
buf += '>'
|
433
|
+
buf
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
class Hash
|
438
|
+
# <code>self</code>を多重連想配列に変換し、その結果を返します。
|
439
|
+
# 新しく生成される多重連想配列においてキーに割り当てられる値は、
|
440
|
+
# <code>self</code>におけるキーの値をMultiset.parseによって多重集合に
|
441
|
+
# 変換したものとなります。
|
442
|
+
#
|
443
|
+
# (例)キー<code>:a</code>には<code>:x</code>と<code>:y</code>が1個ずつ、
|
444
|
+
# キー<code>:b</code>には<code>:x</code>が2個割り当てられた多重連想配列
|
445
|
+
#
|
446
|
+
# <code>{:a => [:x, :y], :b => [:x, :x]}.to_multiset</code>
|
447
|
+
#
|
448
|
+
# Generates multiset from <code>self</code>.
|
449
|
+
# In generated multiset, values associated with a key are defined by
|
450
|
+
# the result of Multiset.parse(values_in_<code>self</code>) .
|
451
|
+
#
|
452
|
+
# (example)
|
453
|
+
# Key <code>:a</code> is associated with values one <code>:x</code> and one <code>:y</code>, and
|
454
|
+
# key <code>:b</code> is associated with values two <code>:x</code>
|
455
|
+
#
|
456
|
+
# <code>{:a => [:x, :y], :b => [:x, :x]}.to_multiset</code>
|
457
|
+
def to_multimap
|
458
|
+
ret = Multimap.new
|
459
|
+
self.each_pair{ |key, val| ret[key] = val }
|
460
|
+
ret
|
461
|
+
end
|
462
|
+
|
463
|
+
# <code>self</code>を多重連想配列に変換し、その結果を返します。
|
464
|
+
# 新しく生成される多重連想配列においてキーに割り当てられる値は、
|
465
|
+
# <code>self</code>に含まれる1要素のみです。
|
466
|
+
#
|
467
|
+
# Generates multiset from <code>self</code>.
|
468
|
+
# In generated multiset, only one value is associated with a key
|
469
|
+
# (value in <code>self</code>).
|
470
|
+
def multimap
|
471
|
+
ret = Multimap.new
|
472
|
+
self.each_pair{ |key, val| ret[key] = Multiset[val] }
|
473
|
+
ret
|
474
|
+
end
|
475
|
+
end
|