跳至內容 跳至搜尋
方法
D
E
F
I
S
T
W

類別公開方法

wrap(object)

將其參數包在陣列中,除非它已經是陣列(或類似陣列)。

具體來說

  • 如果參數為 nil,則傳回一個空陣列。

  • 否則,如果參數回應 to_ary,則呼叫它,並傳回其結果。

  • 否則,傳回一個陣列,其參數為其單一元素。

    Array.wrap(nil)       # => []
    Array.wrap([1, 2, 3]) # => [1, 2, 3]
    Array.wrap(0)         # => [0]
    

此方法在目的上類似於 Kernel#Array,但有一些差異

  • 如果參數回應 to_ary,則呼叫該方法。如果傳回值為 nilKernel#Array 會繼續嘗試 to_a,但 Array.wrap 會立即傳回一個陣列,其參數為其單一元素。

  • 如果 to_ary 的傳回值既不是 nil 也不是 Array 物件,Kernel#Array 會引發例外,而 Array.wrap 則不會,它只會傳回該值。

  • 它不會對參數呼叫 to_a,如果參數沒有回應 to_ary,它會傳回一個陣列,其參數為其單一元素。

最後一點很容易用一些可列舉物來解釋

Array(foo: :bar)      # => [[:foo, :bar]]
Array.wrap(foo: :bar) # => [{:foo=>:bar}]

還有一個相關的慣用語,它使用展開運算子

[*object]

它會傳回 []nil,但會呼叫 Array(object) 給其他情況。

上面說明的 Kernel#Array 差異也適用於其他 object

# File activesupport/lib/active_support/core_ext/array/wrap.rb, line 39
def self.wrap(object)
  if object.nil?
    []
  elsif object.respond_to?(:to_ary)
    object.to_ary || [object]
  else
    [object]
  end
end

執行個體公開方法

deep_dup()

傳回陣列的深度複製。

array = [1, [2, 3]]
dup   = array.deep_dup
dup[1][2] = 4

array[1][2] # => nil
dup[1][2]   # => 4
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 29
def deep_dup
  map(&:deep_dup)
end

excluding(*elements)

傳回排除指定元素的 Array 複製。

["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
[ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]

注意:這是 Enumerable#excluding 的最佳化,它使用 Array#- 代替 Array#reject 以提升效能。

別名為:without
# File activesupport/lib/active_support/core_ext/array/access.rb, line 47
def excluding(*elements)
  self - elements.flatten(1)
end

extract!()

移除並傳回區塊傳回 true 值的元素。如果未提供區塊,則傳回 Enumerator。

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
numbers # => [0, 2, 4, 6, 8]
# File activesupport/lib/active_support/core_ext/array/extract.rb, line 10
def extract!
  return to_enum(:extract!) { size } unless block_given?

  extracted_elements = []

  reject! do |element|
    extracted_elements << element if yield(element)
  end

  extracted_elements
end

extract_options!()

從一組參數中萃取選項。如果陣列中最後一個元素是雜湊,則移除並傳回該元素,否則傳回空白雜湊。

def options(*args)
  args.extract_options!
end

options(1, 2)        # => {}
options(1, 2, a: :b) # => {:a=>:b}
# File activesupport/lib/active_support/core_ext/array/extract_options.rb, line 24
def extract_options!
  if last.is_a?(Hash) && last.extractable_options?
    pop
  else
    {}
  end
end

fifth()

等於 self[4]

%w( a b c d e ).fifth # => "e"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 76
def fifth
  self[4]
end

forty_two()

等於 self[41]。也稱為存取「reddit」。

(1..42).to_a.forty_two # => 42
# File activesupport/lib/active_support/core_ext/array/access.rb, line 83
def forty_two
  self[41]
end

fourth()

等於 self[3]

%w( a b c d e ).fourth # => "d"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 69
def fourth
  self[3]
end

from(position)

傳回陣列中從 position 開始的尾端。

%w( a b c d ).from(0)  # => ["a", "b", "c", "d"]
%w( a b c d ).from(2)  # => ["c", "d"]
%w( a b c d ).from(10) # => []
%w().from(0)           # => []
%w( a b c d ).from(-2) # => ["c", "d"]
%w( a b c ).from(-10)  # => []
# File activesupport/lib/active_support/core_ext/array/access.rb, line 12
def from(position)
  self[position, length] || []
end

in_groups(number, fill_with = nil, &block)

將陣列分割或反覆運算為 number 個群組,除非 fill_withfalse,否則會用 fill_with 填補任何剩餘的插槽。

%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 8 9 10).in_groups(3, '&nbsp;') {|group| p group}
["1", "2", "3", "4"]
["5", "6", "7", "&nbsp;"]
["8", "9", "10", "&nbsp;"]

%w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
["1", "2", "3"]
["4", "5"]
["6", "7"]
# File activesupport/lib/active_support/core_ext/array/grouping.rb, line 62
def in_groups(number, fill_with = nil, &block)
  # size.div number gives minor group size;
  # size % number gives how many objects need extra accommodation;
  # each group hold either division or division + 1 items.
  division = size.div number
  modulo = size % number

  # create a new array avoiding dup
  groups = []
  start = 0

  number.times do |index|
    length = division + (modulo > 0 && modulo > index ? 1 : 0)
    groups << last_group = slice(start, length)
    last_group << fill_with if fill_with != false &&
      modulo > 0 && length == division
    start += length
  end

  if block_given?
    groups.each(&block)
  else
    groups
  end
end

in_groups_of(number, fill_with = nil, &block)

將陣列分割或反覆運算為大小為 number 的群組,除非 fill_withfalse,否則會用 fill_with 填補任何剩餘的插槽。

%w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
["1", "2", "3"]
["4", "5", "6"]
["7", "8", "9"]
["10", nil, nil]

%w(1 2 3 4 5).in_groups_of(2, '&nbsp;') {|group| p group}
["1", "2"]
["3", "4"]
["5", "&nbsp;"]

%w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
["1", "2"]
["3", "4"]
["5"]
# File activesupport/lib/active_support/core_ext/array/grouping.rb, line 22
def in_groups_of(number, fill_with = nil, &block)
  if number.to_i <= 0
    raise ArgumentError,
      "Group size must be a positive integer, was #{number.inspect}"
  end

  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(Array.new(padding, fill_with))
  end

  if block_given?
    collection.each_slice(number, &block)
  else
    collection.each_slice(number).to_a
  end
end

including(*elements)

傳回包含傳入元素的新陣列。

[ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
[ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
# File activesupport/lib/active_support/core_ext/array/access.rb, line 36
def including(*elements)
  self + elements.flatten(1)
end

inquiry()

將陣列包裝在 ActiveSupport::ArrayInquirer 物件中,這提供了更友善的方式來檢查其字串狀內容。

pets = [:cat, :dog].inquiry

pets.cat?     # => true
pets.ferret?  # => false

pets.any?(:cat, :ferret)  # => true
pets.any?(:ferret, :alligator)  # => false
# File activesupport/lib/active_support/core_ext/array/inquiry.rb, line 16
def inquiry
  ActiveSupport::ArrayInquirer.new(self)
end

second()

等於 self[1]

%w( a b c d e ).second # => "b"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 55
def second
  self[1]
end

second_to_last()

等於 self[-2]

%w( a b c d e ).second_to_last # => "d"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 97
def second_to_last
  self[-2]
end

split(value = nil, &block)

根據分隔 value 或選擇性區塊的結果,將陣列分割成一個或多個子陣列。

[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]]
# File activesupport/lib/active_support/core_ext/array/grouping.rb, line 93
def split(value = nil, &block)
  arr = dup
  result = []
  if block_given?
    while (idx = arr.index(&block))
      result << arr.shift(idx)
      arr.shift
    end
  else
    while (idx = arr.index(value))
      result << arr.shift(idx)
      arr.shift
    end
  end
  result << arr
end

third()

等於 self[2]

%w( a b c d e ).third # => "c"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 62
def third
  self[2]
end

third_to_last()

等於 self[-3]

%w( a b c d e ).third_to_last # => "c"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 90
def third_to_last
  self[-3]
end

to(position)

傳回陣列開頭到 position 的部分。

%w( a b c d ).to(0)  # => ["a"]
%w( a b c d ).to(2)  # => ["a", "b", "c"]
%w( a b c d ).to(10) # => ["a", "b", "c", "d"]
%w().to(0)           # => []
%w( a b c d ).to(-2) # => ["a", "b", "c"]
%w( a b c ).to(-10)  # => []
# File activesupport/lib/active_support/core_ext/array/access.rb, line 24
def to(position)
  if position >= 0
    take position + 1
  else
    self[0..position]
  end
end

to_formatted_s(format = :default)

別名為:to_fs

to_fs(format = :default)

延伸 Array#to_s 將元素集合轉換為逗號分隔的 ID 清單,如果給定 :db 參數作為格式。

此方法別名為 to_formatted_s

Blog.all.to_fs(:db)  # => "1,2,3"
Blog.none.to_fs(:db) # => "null"
[1,2].to_fs          # => "[1, 2]"
也別名為:to_formatted_s
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 94
def to_fs(format = :default)
  case format
  when :db
    if empty?
      "null"
    else
      collect(&:id).join(",")
    end
  else
    to_s
  end
end

to_param()

呼叫所有元素的 to_param 並以斜線連接結果。這由 Action Pack 中的 url_for 使用。

# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 42
def to_param
  collect(&:to_param).join "/"
end

to_query(key)

將陣列轉換成適合用作 URL 查詢字串的字串,使用給定的 key 作為參數名稱。

['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 50
def to_query(key)
  prefix = "#{key}[]"

  if empty?
    nil.to_query(prefix)
  else
    collect { |value| value.to_query(prefix) }.join "&"
  end
end

to_sentence(options = {})

將陣列轉換成逗號分隔的句子,其中最後一個元素由連接詞連接。

您可以傳遞下列選項來變更預設行為。如果您傳遞清單中不存在的選項金鑰,它會引發 ArgumentError

選項

  • :words_connector - 用於連接三個或更多元素陣列中所有元素(最後一個元素除外)的符號或字詞(預設值:“, ”)。

  • :last_word_connector - 用於連接三個或更多元素陣列中最後一個元素的符號或字詞(預設值:“, and ”)。

  • :two_words_connector - 用於連接兩個元素陣列中元素的符號或字詞(預設值:“ and ”)。

  • :locale - 如果有 i18n,您可以設定地區設定,並使用對應字典檔中「support.array」命名空間定義的連接器選項。

範例

[].to_sentence                      # => ""
['one'].to_sentence                 # => "one"
['one', 'two'].to_sentence          # => "one and two"
['one', 'two', 'three'].to_sentence # => "one, two, and three"

['one', 'two'].to_sentence(passing: 'invalid option')
# => ArgumentError: Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale

['one', 'two'].to_sentence(two_words_connector: '-')
# => "one-two"

['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
# => "one or two or at least three"

使用 :locale 選項

# Given this locale dictionary:
#
#   es:
#     support:
#       array:
#         words_connector: " o "
#         two_words_connector: " y "
#         last_word_connector: " o al menos "

['uno', 'dos'].to_sentence(locale: :es)
# => "uno y dos"

['uno', 'dos', 'tres'].to_sentence(locale: :es)
# => "uno o dos o al menos tres"
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 60
def to_sentence(options = {})
  options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)

  default_connectors = {
    words_connector: ", ",
    two_words_connector: " and ",
    last_word_connector: ", and "
  }
  if options[:locale] != false && defined?(I18n)
    i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
    default_connectors.merge!(i18n_connectors)
  end
  options = default_connectors.merge!(options)

  case length
  when 0
    +""
  when 1
    +"#{self[0]}"
  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

to_xml(options = {})

透過對每個元素呼叫 to_xml,傳回一個代表 XML 中陣列的字串。Active Record 集合會將它們在 XML 中的表示委派給此方法。

預期所有元素都會回應 to_xml,如果其中任何一個沒有,就會引發例外狀況。

如果所有元素都屬於同種類型,而且不是 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>

否則,根元素為「objects」。

[{ foo: 1, bar: 2}, { baz: 3}].to_xml

<?xml version="1.0" encoding="UTF-8"?>
<objects type="array">
  <object>
    <bar type="integer">2</bar>
    <foo type="integer">1</foo>
  </object>
  <object>
    <baz type="integer">3</baz>
  </object>
</objects>

如果集合是空的,根元素預設為「nil-classes」。

[].to_xml

<?xml version="1.0" encoding="UTF-8"?>
<nil-classes type="array"/>

若要確保根元素有意義,請使用 :root 選項。

customer_with_no_projects.projects.to_xml(root: 'projects')

<?xml version="1.0" encoding="UTF-8"?>
<projects type="array"/>

預設情況下,根子節點的名稱是 root.singularize。您可以使用 :children 選項來變更它。

options hash 會向下傳遞。

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>
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 185
def to_xml(options = {})
  require "active_support/builder" unless defined?(Builder::XmlMarkup)

  options = options.dup
  options[:indent]  ||= 2
  options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
  options[:root]    ||= \
    if first.class != Hash && all?(first.class)
      underscored = ActiveSupport::Inflector.underscore(first.class.name)
      ActiveSupport::Inflector.pluralize(underscored).tr("/", "_")
    else
      "objects"
    end

  builder = options[:builder]
  builder.instruct! unless options.delete(:skip_instruct)

  root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
  children = options.delete(:children) || root.singularize
  attributes = options[:skip_types] ? {} : { type: "array" }

  if empty?
    builder.tag!(root, attributes)
  else
    builder.tag!(root, attributes) do
      each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) }
      yield builder if block_given?
    end
  end
end

without(*elements)

別名:excluding