Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
83fd1ae1
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
83fd1ae1
编写于
3月 21, 2009
作者:
J
Jeremy Kemper
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Convert array extension modules to class reopens
上级
d5e87e3b
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
314 addition
and
348 deletion
+314
-348
activesupport/lib/active_support/core_ext/array.rb
activesupport/lib/active_support/core_ext/array.rb
+5
-2
activesupport/lib/active_support/core_ext/array/access.rb
activesupport/lib/active_support/core_ext/array/access.rb
+39
-46
activesupport/lib/active_support/core_ext/array/conversions.rb
...esupport/lib/active_support/core_ext/array/conversions.rb
+167
-179
activesupport/lib/active_support/core_ext/array/extract_options.rb
...port/lib/active_support/core_ext/array/extract_options.rb
+12
-18
activesupport/lib/active_support/core_ext/array/grouping.rb
activesupport/lib/active_support/core_ext/array/grouping.rb
+87
-93
activesupport/lib/active_support/core_ext/array/random_access.rb
...upport/lib/active_support/core_ext/array/random_access.rb
+4
-10
未找到文件。
activesupport/lib/active_support/core_ext/array.rb
浏览文件 @
83fd1ae1
require
'active_support/core_ext/util'
require
'active_support/core_ext/array/wrap'
ActiveSupport
.
core_ext
Array
,
%w(access conversions extract_options grouping random_access)
require
'active_support/core_ext/array/access'
require
'active_support/core_ext/array/conversions'
require
'active_support/core_ext/array/extract_options'
require
'active_support/core_ext/array/grouping'
require
'active_support/core_ext/array/random_access'
activesupport/lib/active_support/core_ext/array/access.rb
浏览文件 @
83fd1ae1
module
ActiveSupport
#:nodoc:
module
CoreExtensions
#:nodoc:
module
Array
#:nodoc:
# Makes it easier to access parts of an array.
module
Access
# Returns the tail of the array from +position+.
#
# %w( a b c d ).from(0) # => %w( a b c d )
# %w( a b c d ).from(2) # => %w( c d )
# %w( a b c d ).from(10) # => nil
# %w().from(0) # => nil
def
from
(
position
)
self
[
position
..-
1
]
end
# Returns the beginning of the array up to +position+.
#
# %w( a b c d ).to(0) # => %w( a )
# %w( a b c d ).to(2) # => %w( a b c )
# %w( a b c d ).to(10) # => %w( a b c d )
# %w().to(0) # => %w()
def
to
(
position
)
self
[
0
..
position
]
end
class
Array
# Returns the tail of the array from +position+.
#
# %w( a b c d ).from(0) # => %w( a b c d )
# %w( a b c d ).from(2) # => %w( c d )
# %w( a b c d ).from(10) # => nil
# %w().from(0) # => nil
def
from
(
position
)
self
[
position
..-
1
]
end
# Equal to <tt>self[1]</tt>.
def
second
self
[
1
]
end
# Returns the beginning of the array up to +position+.
#
# %w( a b c d ).to(0) # => %w( a )
# %w( a b c d ).to(2) # => %w( a b c )
# %w( a b c d ).to(10) # => %w( a b c d )
# %w().to(0) # => %w()
def
to
(
position
)
self
[
0
..
position
]
end
# Equal to <tt>self[2
]</tt>.
def
thir
d
self
[
2
]
end
# Equal to <tt>self[1
]</tt>.
def
secon
d
self
[
1
]
end
# Equal to <tt>self[3
]</tt>.
def
fourth
self
[
3
]
end
# Equal to <tt>self[2
]</tt>.
def
third
self
[
2
]
end
# Equal to <tt>self[4]</tt>.
def
fifth
self
[
4
]
end
# Equal to <tt>self[3]</tt>.
def
fourth
self
[
3
]
end
# Equal to <tt>self[4]</tt>.
def
fifth
self
[
4
]
end
# Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".
def
forty_two
self
[
41
]
end
end
end
# Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".
def
forty_two
self
[
41
]
end
end
activesupport/lib/active_support/core_ext/array/conversions.rb
浏览文件 @
83fd1ae1
module
ActiveSupport
#:nodoc:
module
CoreExtensions
#:nodoc:
module
Array
#:nodoc:
module
Conversions
# Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:
# * <tt>:words_connector</tt> - The sign or word used to join the elements in arrays with two or more elements (default: ", ")
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements in arrays with two elements (default: " and ")
# * <tt>:last_word_connector</tt> - The sign or word used to join the last element in arrays with three or more elements (default: ", and ")
def
to_sentence
(
options
=
{})
default_words_connector
=
I18n
.
translate
(
:'support.array.words_connector'
,
:locale
=>
options
[
:locale
])
default_two_words_connector
=
I18n
.
translate
(
:'support.array.two_words_connector'
,
:locale
=>
options
[
:locale
])
default_last_word_connector
=
I18n
.
translate
(
:'support.array.last_word_connector'
,
:locale
=>
options
[
:locale
])
class
Array
# Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:
# * <tt>:words_connector</tt> - The sign or word used to join the elements in arrays with two or more elements (default: ", ")
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements in arrays with two elements (default: " and ")
# * <tt>:last_word_connector</tt> - The sign or word used to join the last element in arrays with three or more elements (default: ", and ")
def
to_sentence
(
options
=
{})
default_words_connector
=
I18n
.
translate
(
:'support.array.words_connector'
,
:locale
=>
options
[
:locale
])
default_two_words_connector
=
I18n
.
translate
(
:'support.array.two_words_connector'
,
:locale
=>
options
[
:locale
])
default_last_word_connector
=
I18n
.
translate
(
:'support.array.last_word_connector'
,
:locale
=>
options
[
:locale
])
# Try to emulate to_senteces previous to 2.3
if
options
.
has_key?
(
:connector
)
||
options
.
has_key?
(
:skip_last_comma
)
::
ActiveSupport
::
Deprecation
.
warn
(
":connector has been deprecated. Use :words_connector instead"
,
caller
)
if
options
.
has_key?
:connector
::
ActiveSupport
::
Deprecation
.
warn
(
":skip_last_comma has been deprecated. Use :last_word_connector instead"
,
caller
)
if
options
.
has_key?
:skip_last_comma
# Try to emulate to_senteces previous to 2.3
if
options
.
has_key?
(
:connector
)
||
options
.
has_key?
(
:skip_last_comma
)
::
ActiveSupport
::
Deprecation
.
warn
(
":connector has been deprecated. Use :words_connector instead"
,
caller
)
if
options
.
has_key?
:connector
::
ActiveSupport
::
Deprecation
.
warn
(
":skip_last_comma has been deprecated. Use :last_word_connector instead"
,
caller
)
if
options
.
has_key?
:skip_last_comma
skip_last_comma
=
options
.
delete
:skip_last_comma
if
connector
=
options
.
delete
(
:connector
)
options
[
:last_word_connector
]
||=
skip_last_comma
?
connector
:
",
#{
connector
}
"
else
options
[
:last_word_connector
]
||=
skip_last_comma
?
default_two_words_connector
:
default_last_word_connector
end
end
options
.
assert_valid_keys
(
:words_connector
,
:two_words_connector
,
:last_word_connector
,
:locale
)
options
.
reverse_merge!
:words_connector
=>
default_words_connector
,
:two_words_connector
=>
default_two_words_connector
,
:last_word_connector
=>
default_last_word_connector
case
length
when
0
""
when
1
self
[
0
].
to_s
when
2
"
#{
self
[
0
]
}#{
options
[
:two_words_connector
]
}#{
self
[
1
]
}
"
else
"
#{
self
[
0
...-
1
].
join
(
options
[
:words_connector
])
}#{
options
[
:last_word_connector
]
}#{
self
[
-
1
]
}
"
end
end
skip_last_comma
=
options
.
delete
:skip_last_comma
if
connector
=
options
.
delete
(
:connector
)
options
[
:last_word_connector
]
||=
skip_last_comma
?
connector
:
",
#{
connector
}
"
else
options
[
:last_word_connector
]
||=
skip_last_comma
?
default_two_words_connector
:
default_last_word_connector
end
end
# Calls <tt>to_param</tt> on all its elements and joins the result with
# slashes. This is used by <tt>url_for</tt> in Action Pack.
def
to_param
collect
{
|
e
|
e
.
to_param
}.
join
'/'
end
options
.
assert_valid_keys
(
:words_connector
,
:two_words_connector
,
:last_word_connector
,
:locale
)
options
.
reverse_merge!
:words_connector
=>
default_words_connector
,
:two_words_connector
=>
default_two_words_connector
,
:last_word_connector
=>
default_last_word_connector
# Converts an array into a string suitable for use as a URL query string,
# using the given +key+ as the param name.
#
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
def
to_query
(
key
)
prefix
=
"
#{
key
}
[]"
collect
{
|
value
|
value
.
to_query
(
prefix
)
}.
join
'&'
end
case
length
when
0
""
when
1
self
[
0
].
to_s
when
2
"
#{
self
[
0
]
}#{
options
[
:two_words_connector
]
}#{
self
[
1
]
}
"
else
"
#{
self
[
0
...-
1
].
join
(
options
[
:words_connector
])
}#{
options
[
:last_word_connector
]
}#{
self
[
-
1
]
}
"
end
end
def
self
.
included
(
base
)
#:nodoc:
base
.
class_eval
do
alias_method
:to_default_s
,
:to_s
alias_method
:to_s
,
:to_formatted_s
end
end
# Converts a collection of elements into a formatted string by calling
# <tt>to_s</tt> on all elements and joining them:
#
# Blog.find(:all).to_formatted_s # => "First PostSecond PostThird Post"
#
# Adding in the <tt>:db</tt> argument as the format yields a prettier
# output:
#
# Blog.find(:all).to_formatted_s(:db) # => "First Post,Second Post,Third Post"
def
to_formatted_s
(
format
=
:default
)
case
format
when
:db
if
respond_to?
(
:empty?
)
&&
self
.
empty?
"null"
else
collect
{
|
element
|
element
.
id
}.
join
(
","
)
end
else
to_default_s
end
end
# Calls <tt>to_param</tt> on all its elements and joins the result with
# slashes. This is used by <tt>url_for</tt> in Action Pack.
def
to_param
collect
{
|
e
|
e
.
to_param
}.
join
'/'
end
# Returns a string that represents this array in XML by sending +to_xml+
# to each element. Active Record collections delegate their representation
# in XML to this method.
#
# All elements are expected to respond to +to_xml+, if any of them does
# not an exception is raised.
#
# The root node reflects the class name of the first element in plural
# if all elements belong to the same type and that's not Hash:
#
# customer.projects.to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <projects type="array">
# <project>
# <amount type="decimal">20000.0</amount>
# <customer-id type="integer">1567</customer-id>
# <deal-date type="date">2008-04-09</deal-date>
# ...
# </project>
# <project>
# <amount type="decimal">57230.0</amount>
# <customer-id type="integer">1567</customer-id>
# <deal-date type="date">2008-04-15</deal-date>
# ...
# </project>
# </projects>
#
# Otherwise the root element is "records":
#
# [{:foo => 1, :bar => 2}, {:baz => 3}].to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <records type="array">
# <record>
# <bar type="integer">2</bar>
# <foo type="integer">1</foo>
# </record>
# <record>
# <baz type="integer">3</baz>
# </record>
# </records>
#
# If the collection is empty the root element is "nil-classes" by default:
#
# [].to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <nil-classes type="array"/>
#
# To ensure a meaningful root element use the <tt>:root</tt> option:
#
# customer_with_no_projects.projects.to_xml(:root => "projects")
#
# <?xml version="1.0" encoding="UTF-8"?>
# <projects type="array"/>
#
# By default root children have as node name the one of the root
# singularized. You can change it with the <tt>:children</tt> option.
#
# The +options+ hash is passed downwards:
#
# Message.all.to_xml(:skip_types => true)
#
# <?xml version="1.0" encoding="UTF-8"?>
# <messages>
# <message>
# <created-at>2008-03-07T09:58:18+01:00</created-at>
# <id>1</id>
# <name>1</name>
# <updated-at>2008-03-07T09:58:18+01:00</updated-at>
# <user-id>1</user-id>
# </message>
# </messages>
#
def
to_xml
(
options
=
{})
raise
"Not all elements respond to to_xml"
unless
all?
{
|
e
|
e
.
respond_to?
:to_xml
}
require
'builder'
unless
defined?
(
Builder
)
# Converts an array into a string suitable for use as a URL query string,
# using the given +key+ as the param name.
#
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
def
to_query
(
key
)
prefix
=
"
#{
key
}
[]"
collect
{
|
value
|
value
.
to_query
(
prefix
)
}.
join
'&'
end
options
[
:root
]
||=
all?
{
|
e
|
e
.
is_a?
(
first
.
class
)
&&
first
.
class
.
to_s
!=
"Hash"
}
?
first
.
class
.
to_s
.
underscore
.
pluralize
:
"records"
options
[
:children
]
||=
options
[
:root
].
singularize
options
[
:indent
]
||=
2
options
[
:builder
]
||=
Builder
::
XmlMarkup
.
new
(
:indent
=>
options
[
:indent
])
# Converts a collection of elements into a formatted string by calling
# <tt>to_s</tt> on all elements and joining them:
#
# Blog.find(:all).to_formatted_s # => "First PostSecond PostThird Post"
#
# Adding in the <tt>:db</tt> argument as the format yields a prettier
# output:
#
# Blog.find(:all).to_formatted_s(:db) # => "First Post,Second Post,Third Post"
def
to_formatted_s
(
format
=
:default
)
case
format
when
:db
if
respond_to?
(
:empty?
)
&&
self
.
empty?
"null"
else
collect
{
|
element
|
element
.
id
}.
join
(
","
)
end
else
to_default_s
end
end
alias_method
:to_default_s
,
:to_s
alias_method
:to_s
,
:to_formatted_s
root
=
options
.
delete
(
:root
).
to_s
children
=
options
.
delete
(
:children
)
# Returns a string that represents this array in XML by sending +to_xml+
# to each element. Active Record collections delegate their representation
# in XML to this method.
#
# All elements are expected to respond to +to_xml+, if any of them does
# not an exception is raised.
#
# The root node reflects the class name of the first element in plural
# if all elements belong to the same type and that's not Hash:
#
# customer.projects.to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <projects type="array">
# <project>
# <amount type="decimal">20000.0</amount>
# <customer-id type="integer">1567</customer-id>
# <deal-date type="date">2008-04-09</deal-date>
# ...
# </project>
# <project>
# <amount type="decimal">57230.0</amount>
# <customer-id type="integer">1567</customer-id>
# <deal-date type="date">2008-04-15</deal-date>
# ...
# </project>
# </projects>
#
# Otherwise the root element is "records":
#
# [{:foo => 1, :bar => 2}, {:baz => 3}].to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <records type="array">
# <record>
# <bar type="integer">2</bar>
# <foo type="integer">1</foo>
# </record>
# <record>
# <baz type="integer">3</baz>
# </record>
# </records>
#
# If the collection is empty the root element is "nil-classes" by default:
#
# [].to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <nil-classes type="array"/>
#
# To ensure a meaningful root element use the <tt>:root</tt> option:
#
# customer_with_no_projects.projects.to_xml(:root => "projects")
#
# <?xml version="1.0" encoding="UTF-8"?>
# <projects type="array"/>
#
# By default root children have as node name the one of the root
# singularized. You can change it with the <tt>:children</tt> option.
#
# The +options+ hash is passed downwards:
#
# Message.all.to_xml(:skip_types => true)
#
# <?xml version="1.0" encoding="UTF-8"?>
# <messages>
# <message>
# <created-at>2008-03-07T09:58:18+01:00</created-at>
# <id>1</id>
# <name>1</name>
# <updated-at>2008-03-07T09:58:18+01:00</updated-at>
# <user-id>1</user-id>
# </message>
# </messages>
#
def
to_xml
(
options
=
{})
raise
"Not all elements respond to to_xml"
unless
all?
{
|
e
|
e
.
respond_to?
:to_xml
}
require
'builder'
unless
defined?
(
Builder
)
if
!
options
.
has_key?
(
:dasherize
)
||
options
[
:dasherize
]
root
=
root
.
dasherize
end
options
[
:root
]
||=
all?
{
|
e
|
e
.
is_a?
(
first
.
class
)
&&
first
.
class
.
to_s
!=
"Hash"
}
?
first
.
class
.
to_s
.
underscore
.
pluralize
:
"records"
options
[
:children
]
||=
options
[
:root
].
singularize
options
[
:indent
]
||=
2
options
[
:builder
]
||=
Builder
::
XmlMarkup
.
new
(
:indent
=>
options
[
:indent
])
options
[
:builder
].
instruct!
unless
options
.
delete
(
:skip_instruct
)
root
=
options
.
delete
(
:root
).
to_s
children
=
options
.
delete
(
:children
)
opts
=
options
.
merge
({
:root
=>
children
})
if
!
options
.
has_key?
(
:dasherize
)
||
options
[
:dasherize
]
root
=
root
.
dasherize
end
xml
=
options
[
:builder
]
if
empty?
xml
.
tag!
(
root
,
options
[
:skip_types
]
?
{}
:
{
:type
=>
"array"
})
else
xml
.
tag!
(
root
,
options
[
:skip_types
]
?
{}
:
{
:type
=>
"array"
})
{
yield
xml
if
block_given?
each
{
|
e
|
e
.
to_xml
(
opts
.
merge
({
:skip_instruct
=>
true
}))
}
}
end
end
options
[
:builder
].
instruct!
unless
options
.
delete
(
:skip_instruct
)
end
opts
=
options
.
merge
({
:root
=>
children
})
xml
=
options
[
:builder
]
if
empty?
xml
.
tag!
(
root
,
options
[
:skip_types
]
?
{}
:
{
:type
=>
"array"
})
else
xml
.
tag!
(
root
,
options
[
:skip_types
]
?
{}
:
{
:type
=>
"array"
})
{
yield
xml
if
block_given?
each
{
|
e
|
e
.
to_xml
(
opts
.
merge
({
:skip_instruct
=>
true
}))
}
}
end
end
end
activesupport/lib/active_support/core_ext/array/extract_options.rb
浏览文件 @
83fd1ae1
module
ActiveSupport
#:nodoc:
module
CoreExtensions
#:nodoc:
module
Array
#:nodoc:
module
ExtractOptions
# Extracts options from a set of arguments. Removes and returns the last
# element in the array if it's a hash, otherwise returns a blank hash.
#
# def options(*args)
# args.extract_options!
# end
#
# options(1, 2) # => {}
# options(1, 2, :a => :b) # => {:a=>:b}
def
extract_options!
last
.
is_a?
(
::
Hash
)
?
pop
:
{}
end
end
end
class
Array
# Extracts options from a set of arguments. Removes and returns the last
# element in the array if it's a hash, otherwise returns a blank hash.
#
# def options(*args)
# args.extract_options!
# end
#
# options(1, 2) # => {}
# options(1, 2, :a => :b) # => {:a=>:b}
def
extract_options!
last
.
is_a?
(
::
Hash
)
?
pop
:
{}
end
end
activesupport/lib/active_support/core_ext/array/grouping.rb
浏览文件 @
83fd1ae1
require
'enumerator'
module
ActiveSupport
#:nodoc:
module
CoreExtensions
#:nodoc:
module
Array
#:nodoc:
module
Grouping
# Splits or iterates over the array in groups of size +number+,
# padding any remaining slots with +fill_with+ unless it is +false+.
#
# %w(1 2 3 4 5 6 7).in_groups_of(3) {|group| p group}
# ["1", "2", "3"]
# ["4", "5", "6"]
# ["7", nil, nil]
#
# %w(1 2 3).in_groups_of(2, ' ') {|group| p group}
# ["1", "2"]
# ["3", " "]
#
# %w(1 2 3).in_groups_of(2, false) {|group| p group}
# ["1", "2"]
# ["3"]
def
in_groups_of
(
number
,
fill_with
=
nil
)
if
fill_with
==
false
collection
=
self
else
# size % number gives how many extra we have;
# subtracting from number gives how many to add;
# modulo number ensures we don't add group of just fill.
padding
=
(
number
-
size
%
number
)
%
number
collection
=
dup
.
concat
([
fill_with
]
*
padding
)
end
if
block_given?
collection
.
each_slice
(
number
)
{
|
slice
|
yield
(
slice
)
}
else
returning
[]
do
|
groups
|
collection
.
each_slice
(
number
)
{
|
group
|
groups
<<
group
}
end
end
end
class
Array
# Splits or iterates over the array in groups of size +number+,
# padding any remaining slots with +fill_with+ unless it is +false+.
#
# %w(1 2 3 4 5 6 7).in_groups_of(3) {|group| p group}
# ["1", "2", "3"]
# ["4", "5", "6"]
# ["7", nil, nil]
#
# %w(1 2 3).in_groups_of(2, ' ') {|group| p group}
# ["1", "2"]
# ["3", " "]
#
# %w(1 2 3).in_groups_of(2, false) {|group| p group}
# ["1", "2"]
# ["3"]
def
in_groups_of
(
number
,
fill_with
=
nil
)
if
fill_with
==
false
collection
=
self
else
# size % number gives how many extra we have;
# subtracting from number gives how many to add;
# modulo number ensures we don't add group of just fill.
padding
=
(
number
-
size
%
number
)
%
number
collection
=
dup
.
concat
([
fill_with
]
*
padding
)
end
# Splits or iterates over the array in +number+ of groups, padding any
# remaining slots with +fill_with+ unless it is +false+.
#
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
# ["1", "2", "3", "4"]
# ["5", "6", "7", nil]
# ["8", "9", "10", nil]
#
# %w(1 2 3 4 5 6 7).in_groups(3, ' ') {|group| p group}
# ["1", "2", "3"]
# ["4", "5", " "]
# ["6", "7", " "]
#
# %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
# ["1", "2", "3"]
# ["4", "5"]
# ["6", "7"]
def
in_groups
(
number
,
fill_with
=
nil
)
# size / number gives minor group size;
# size % number gives how many objects need extra accomodation;
# each group hold either division or division + 1 items.
division
=
size
/
number
modulo
=
size
%
number
if
block_given?
collection
.
each_slice
(
number
)
{
|
slice
|
yield
(
slice
)
}
else
groups
=
[]
collection
.
each_slice
(
number
)
{
|
group
|
groups
<<
group
}
groups
end
end
# create a new array avoiding dup
groups
=
[]
start
=
0
# Splits or iterates over the array in +number+ of groups, padding any
# remaining slots with +fill_with+ unless it is +false+.
#
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
# ["1", "2", "3", "4"]
# ["5", "6", "7", nil]
# ["8", "9", "10", nil]
#
# %w(1 2 3 4 5 6 7).in_groups(3, ' ') {|group| p group}
# ["1", "2", "3"]
# ["4", "5", " "]
# ["6", "7", " "]
#
# %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
# ["1", "2", "3"]
# ["4", "5"]
# ["6", "7"]
def
in_groups
(
number
,
fill_with
=
nil
)
# size / number gives minor group size;
# size % number gives how many objects need extra accomodation;
# each group hold either division or division + 1 items.
division
=
size
/
number
modulo
=
size
%
number
number
.
times
do
|
index
|
length
=
division
+
(
modulo
>
0
&&
modulo
>
index
?
1
:
0
)
padding
=
fill_with
!=
false
&&
modulo
>
0
&&
length
==
division
?
1
:
0
groups
<<
slice
(
start
,
length
).
concat
([
fill_with
]
*
padding
)
start
+=
length
end
# create a new array avoiding dup
groups
=
[]
start
=
0
if
block_given?
groups
.
each
{
|
g
|
yield
(
g
)
}
else
groups
end
end
number
.
times
do
|
index
|
length
=
division
+
(
modulo
>
0
&&
modulo
>
index
?
1
:
0
)
padding
=
fill_with
!=
false
&&
modulo
>
0
&&
length
==
division
?
1
:
0
groups
<<
slice
(
start
,
length
).
concat
([
fill_with
]
*
padding
)
start
+=
length
end
# Divides the array into one or more subarrays based on a delimiting +value+
# or the result of an optional block.
#
# [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
def
split
(
value
=
nil
)
using_block
=
block_given?
if
block_given?
groups
.
each
{
|
g
|
yield
(
g
)
}
else
groups
end
end
inject
([[]])
do
|
results
,
element
|
if
(
using_block
&&
yield
(
element
))
||
(
value
==
element
)
results
<<
[]
else
results
.
last
<<
element
end
# Divides the array into one or more subarrays based on a delimiting +value+
# or the result of an optional block.
#
# [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
def
split
(
value
=
nil
)
using_block
=
block_given?
results
end
end
inject
([[]])
do
|
results
,
element
|
if
(
using_block
&&
yield
(
element
))
||
(
value
==
element
)
results
<<
[]
else
results
.
last
<<
element
end
results
end
end
end
activesupport/lib/active_support/core_ext/array/random_access.rb
浏览文件 @
83fd1ae1
module
ActiveSupport
#:nodoc:
module
CoreExtensions
#:nodoc:
module
Array
#:nodoc:
module
RandomAccess
# Returns a random element from the array.
def
rand
self
[
Kernel
.
rand
(
length
)]
end
end
end
class
Array
# Returns a random element from the array.
def
rand
self
[
Kernel
.
rand
(
length
)]
end
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录