Заполнить разреженный массив - PullRequest
0 голосов
/ 17 сентября 2010

У меня есть разреженный массив, например:

rare = [[0,1], [2,3], [4,5], [7,8]]

Я хочу построить график с этими данными, каждая пара - это координаты точки.Как вы видите, у меня нет точек для x = 1, x = 3, x = 5, x = 6

Я хочу заполнить массив предыдущими значениями, поэтому для приведенного выше примера я будуget:

filled = [[0,1], [1,1], [2,3], [3,3], [4,5], [5,5], [6,5], [7,8]

Как видите, для вычисления значения y я просто беру последнее значение y, которое я использовал.

Каков наилучший подход для достижения этой цели?

Ответы [ 4 ]

6 голосов
/ 17 сентября 2010
Range.new(*rare.transpose.first.sort.values_at(0,-1)).inject([]){|a,i|
  a<<[i, Hash[rare][i] || a.last.last]
}

Пошаговое объяснение:

  1. rare.transpose.first.sort.values_at(0,-1) находит минимальное и максимальное значения x ([0,7] в вашем примере)
  2. Range.new() делаетдиапазон из него (0..7)
  3. inject перебирает диапазон и для каждой x возвращает пару [x,y], где y:
    1. yиз входного массива, где определено
    2. y из ранее оцененной пары, где нет

Примечание: вот некоторые другие способы нахождения min и max x:

[:min,:max].map{|m| Hash[rare].keys.send m}
rare.map{|el| el.first}.minmax # Ruby 1.9, by steenslag
2 голосов
/ 17 сентября 2010

Решение inject:

filled = rare.inject([]) do |filled_acc, (pair_x, pair_y)|
  padded_pairs = unless filled_acc.empty?    
    last_x, last_y = filled_acc.last
    (last_x+1...pair_x).map { |x| [x, last_y] }
  end || []
  filled_acc + padded_pairs + [[pair_x, pair_y]] 
end

Подробнее о Enumerable#inject и функциональном программировании на Ruby здесь .

2 голосов
/ 17 сентября 2010
rare = [[0,1], [2,3], [4,5], [7,8]]

filled = rare.inject([]) do |filled, point|
  extras = if filled.empty?
             []
           else
             (filled.last[0] + 1 ... point[0]).collect do |x|
               [x, filled.last[1]]
             end
           end
  filled + extras + [point]
end

p filled
# => [[0, 1], [1, 1], [2, 3], [3, 3], [4, 5], [5, 5], [6, 5], [7, 8]]
0 голосов
/ 18 сентября 2010
irb(main):001:0> rare = [[0,1], [2,3], [4,5], [7,8]]
=> [[0, 1], [2, 3], [4, 5], [7, 8]]
irb(main):002:0> r=rare.transpose
=> [[0, 2, 4, 7], [1, 3, 5, 8]]
irb(main):003:0> iv = (r[0][0]..r[0][-1]).to_a.select {|w| !r[0].include?(w) }
=> [1, 3, 5, 6]
irb(main):004:0> r[1][-1]=r[1][-2]
=> 5
irb(main):005:0> p (iv.zip(r[1]) + rare).sort
[[0, 1], [1, 1], [2, 3], [3, 3], [4, 5], [5, 5], [6, 5], [7, 8]]
=> [[0, 1], [1, 1], [2, 3], [3, 3], [4, 5], [5, 5], [6, 5], [7, 8]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...