2010-09-17 81 views
0

我有一个稀疏阵列,例如:填充稀疏数组

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

我要绘制的图表与这些数据,每一对是点坐标。 正如你所看到的,我没有x = 1,x = 3,x = 5,x = 6的点数。我想用前面的值填充数组,所以对于上面的例子,我会得到:

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

正如你所看到的,为了计算y值,我简单地取我使用的最后一个y值。

什么是最好的方法来实现这一目标?

回答

6
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是:这里是找到最小和最大x的其他一些方法::

    1. 从输入阵列,其中从先前评价对定义
    2. y,其中不

y

+0

小心通过那个与我们谈谈?我认为它会工作,但它不是特别可读:) – Glenjamin 2010-09-17 14:48:44

+0

它空的“罕见”失败。我会说,使用<<与注射是有点作弊,但它肯定会更快。 – tokland 2010-09-17 14:51:30

+0

@Glenjamin:我给了我最好的:) @tokland:谢谢你的错误报告,你为什么认为'''注射是作弊?作弊可以使用'inject',其中'map'是逻辑的(因为我将数组映射到另一个),但是我需要以前的值,因此需要'inject'。 – 2010-09-17 15:01:21

2
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

请注意@astropanic,我的解决方案和Wayne's是virt真的是一样的(只有他快了4分钟)。 – tokland 2010-09-17 14:25:46

+0

@tokland,:)如果我是你,我就会陷入困境。从我这里拿出来:这里很可怕! – 2010-09-17 15:20:48

2

一种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并用红宝石here功能的编程。

0
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]]