Создание двумерных массивов и доступ к подмассивам в Ruby

Интересно, есть ли возможность создать двумерный массив и быстро получить к нему доступ к любому горизонтальному или вертикальному подмассиву?

Я полагаю, что мы можем получить доступ к горизонтальному подмассиву в следующем случае:

x = Array.new(10) { Array.new(20) }

x[6][3..8] = 'something'

Но, насколько я понимаю, мы не можем получить к нему доступ следующим образом:

x[3..8][6]

Как я могу избежать или взломать этот предел?

66 голосов | спросил gmile 12 42009vEurope/Moscow11bEurope/MoscowThu, 12 Nov 2009 12:12:56 +0300 2009, 12:12:56

9 ответов


0

Есть некоторые проблемы с двухмерным Arrays способом их реализации.

a= [[1,2],[3,4]]
a[0][2]= 5 # works
a[2][0]= 6 # error

Hash как Array

Я предпочитаю использовать Hashes для многомерного Arrays

a= Hash.new
a[[1,2]]= 23
a[[5,6]]= 42

Это имеет то преимущество, что вам не нужно вручную создавать столбцы или строки. Вставка в хэши - это почти O (1) , поэтому здесь нет недостатка, поскольку так как ваш Hash не станет слишком большим.

Вы даже можете установить значение по умолчанию для всех не указанных элементов

a= Hash.new(0)

Итак, теперь о том, как получить подмассивы

(3..5).to_a.product([2]).collect { |index| a[index] }
[2].product((3..5).to_a).collect { |index| a[index] }

(a..b).to_a работает в O (n). Извлечение элемента из Hash почти равно O (1), поэтому сбор выполняется почти за O (n). Невозможно сделать это быстрее, чем O (n), поскольку копирование n элементов всегда равно O (n).

Hashes могут возникнуть проблемы, когда они становятся слишком большими. Поэтому я бы дважды подумал о реализации многомерного Array таким образом, если бы знал, что объем моих данных становится большим.

ответил johannes 12 42009vEurope/Moscow11bEurope/MoscowThu, 12 Nov 2009 14:54:18 +0300 2009, 14:54:18
0
rows, cols = x,y  # your values
grid = Array.new(rows) { Array.new(cols) }

Что касается доступа к элементам, эта статья довольно хороша для пошагового способа инкапсуляции массива так, как вы хотите:

Как создать массив ruby ​​

ответил shawnjan 12 42009vEurope/Moscow11bEurope/MoscowThu, 12 Nov 2009 12:19:28 +0300 2009, 12:19:28
0

Вы не указали свою реальную цель, но, возможно, это поможет:

require 'matrix'  # bundled with Ruby
m = Matrix[
 [1, 2, 3],
 [4, 5, 6]
]

m.column(0) # ==> Vector[1, 4]

(а Векторы действуют как массивы)

или, используя ту же запись, что и вы:

m.minor(0..1, 2..2) # => Matrix[[3], [6]]
ответил Marc-André Lafortune 12 42009vEurope/Moscow11bEurope/MoscowThu, 12 Nov 2009 15:29:08 +0300 2009, 15:29:08
0

Вот случай с трехмерным массивом

class Array3D
   def initialize(d1,d2,d3)
    @data = Array.new(d1) { Array.new(d2) { Array.new(d3) } }
   end

  def [](x, y, z)
    @data[x][y][z]
  end

  def []=(x, y, z, value)
    @data[x][y][z] = value
  end
end

Вы можете получить доступ к подразделам каждого массива, как и любой другой массив Ruby. @data [0..2] [3..5] [8..10] = 0 и т.д.

ответил Mark Essel 15 J000000Thursday10 2010, 00:32:30
0

x.transpose[6][3..8] или x[3..8].map {|r| r [6]} что ты хочешь.

Пример:

a = [ [1,  2,  3,  4,  5],
      [6,  7,  8,  9,  10],
      [11, 12, 13, 14, 15],
      [21, 22, 23, 24, 25]
    ]

#a[1..2][2]  -> [8,13]
puts a.transpose[2][1..2].inspect   # [8,13]
puts a[1..2].map {|r| r[2]}.inspect  # [8,13]
ответил pierrotlefou 12 42009vEurope/Moscow11bEurope/MoscowThu, 12 Nov 2009 12:46:40 +0300 2009, 12:46:40
0

Я совершенно уверен, что это может быть очень просто

2.0.0p247 :032 > list = Array.new(5)

 => [nil, nil, nil, nil, nil] 

2.0.0p247 :033 > list.map!{ |x| x = [0] }

 => [[0], [0], [0], [0], [0]] 

2.0.0p247 :034 > list[0][0]

  => 0
ответил vladCovaliov 17 +04002013-10-17T23:42:11+04:00312013bEurope/MoscowThu, 17 Oct 2013 23:42:11 +0400 2013, 23:42:11
0
a = Array.new(Array.new(4))

0.upto(a.length-1) do |i|
  0.upto(a.length-1) do |j|
    a[i[j]] = 1
  end
end

0.upto(a.length-1) do |i|
  0.upto(a.length-1) do |j|
    print a[i[j]] = 1 #It's not a[i][j], but a[i[j]]
  end
  puts "\n"
end
ответил anon 14 FebruaryEurope/MoscowbThu, 14 Feb 2013 21:00:14 +0400000000pmThu, 14 Feb 2013 21:00:14 +040013 2013, 21:00:14
0

Вот простая версия

 #one
 a = [[0]*10]*10

 #two
row, col = 10, 10
a = [[0]*row]*col
ответил mohan 23 Jam1000000amWed, 23 Jan 2013 09:39:54 +040013 2013, 09:39:54
0

Вот простой способ создания "2D" массива.

2.1.1 :004 > m=Array.new(3,Array.new(3,true))

=> [[true, true, true], [true, true, true], [true, true, true]]
ответил amcritchie 27 J000000Sunday14 2014, 07:11:36

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132