2016-06-17 27 views
0

好的,所以我有这个数组数组。较大阵列中的每个阵列都非常相同,有十个特定值。如果我在位置3的值是一个特定值,那么我想遍历更大阵列中其余数组的其余部分,并查看位置0,1和2的前3个值是否匹配。如果它们匹配,我想删除原始数组。我很难与它,也许有一个简单的方法?我敢肯定有,我是相当新的这整个编码的东西=)这么多的感谢提前对你的帮助....从多维数组中删除数组如果前3个值在轨道上的ruby中不唯一

这里就是我在:

@projectsandtrials.each do |removed| 
    if removed[3] == ["Not Harvested"] 
    @arraysforloop = @projectsandtrials.clone 
    @arraysforloop1 = @arraysforloop.clone.delete(removed) 
    @arraysforloop1.each do |m| 
     if (m & [removed[0], removed[1], removed[2]]).any? 
     @projectsandtrials.delete(removed) 
     end 
    end 


    end 

end 
+0

我遇到的问题是,我的第一个数组从@projectsandtrials中删除,它不应该是......但其他一切都很好...... – bwatson30

+0

请编辑一个小例子,包括您的预期结果。而不是数组大小为10,使它们更小 - 比如5个元素。如果您愿意,请随时使用我在答案中给出的例子。 –

回答

3

让看看你的情况:

@projectsandtrials.each do |removed| 
    // some logic, yada yada 
    @projectsandtrials.delete(removed) 
end 

你不能只删除你迭代的数组中的东西。至少直到你完成迭代。您应该使用的是像reject这样的过滤方法,而不仅仅是each

因此,而不是删除在那里的,你应该使用拒绝时,刚刚返回true。

在迭代数组时,我会这样想。

做我想做的阵列保持相同尺寸并具有相同的内容? 使用each

做我想做的阵列是相同的大小,但具有不同的内容? 使用map

做我想做的阵列小于或等于当前大小?使用selectreject

我想让它最终成为一个单一的值吗? 使用reduce

+0

谢谢@arjabbar,以及其他所有人。我的初始解决方案非常简单 - 就像你说的,我需要等待删除我的数组,直到完成迭代。所以,这工作,但我也继续前进和清理它,并重构它使用拒绝方法!谢谢大家!总是一种学习体验,并且很乐意听到不同的思考方式! – bwatson30

0

您的代码段似乎罚款,虽然有几件事情需要注意:

  1. @arraysforloop.clone.delete(removed)删除removed阵列(不仅是第一个)的所有出现次数。例如。 [1,2,3,1] .delete(1)会给你留下[2,3]。您可以使用迭代器对@projectsandtrialsdelete_at方法进行修复。

  2. delete方法返回您传递给它(或零,如果没有找到任何匹配)相同的说法。因此@arraysforloop1 = @arraysforloop.clone.delete(removed)使您的@arraysforloop1仅包含已删除的数组元素!删除作业可以节省您。

  3. 我没有理由有两个克隆阵列,@arraysforloop@arraysforloop1,因为前者不会在以后使用。可能我们可以忽略其中的一个?

  4. @projectsandtrials.delete(removed)让你在一个陌生的国家,只要你迭代在同一阵列现在。这可能会导致您在删除之后错过了正确的下一个元素。下面是一个简单的代码片段来说明问题:

    > a = [1,2,3] 
    > a.each{|e, index| puts("element is: #{e}"); a.delete(1);} 
    element is: 1 
    element is: 3 
    

    正如你看到的,删除元素1后的环移到元素3直接,省略2(因为它成为数组的第一个元素和算法认为它已经已处理)。

使其不那么混乱的一种可能性是将其拆分为一束方法。下面是一个选项:

def has_searched_element? row 
    # I leave this method implementation to you 
end 

def next_rows_contain_three_duplicates?(elements, index) 
    # I leave this method implementation to you 
end 

def find_row_ids_to_remove elements 
    [].tap do |result| 
    elements.each_with_index do |row, index| 
     condition = has_searched_element?(row) && next_rows_contain_three_duplicates?(elements, index) 
     result << index if condition 
    end 
    end 
end 

row_ids_to_remove = find_row_ids_to_remove(@projectsandtrials) 
# now remove all the elements at those ids out of @projectsandtrials 
1

代码

def prune(arr, val) 
    arr.values_at(*(0..arr.size-4).reject { |i| arr[i][3] == val && 
    arr[i+1..i+3].transpose[0,3].map(&:uniq).all? { |a| a.size==1 } }. 
     concat((arr.size-3..arr.size-1).to_a)) 
end 

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

注意的arr元件(阵列)的最后的值是连续的。这是为了帮助您识别已被删除的prune(arr, 4)(下文)的元素。

prune(arr, 4) 
    # => [[3, 4, 5, 6, 1], 
    #  [3, 4, 5, 4, 2], 
    #  [3, 4, 5, 6, 3], 
    #  [3, 4, 5, 6, 4], 
    #  [3, 4, 0, 6, 5], 
    #  [2, 3, 5, 5, 7], 
    #  [2, 3, 5, 7, 8], 
    #  [2, 3, 5, 8, 9], 
    #  [2, 3, 5, 7, 0]] 

说明

在索引06的阵列还没有被包含在阵列返回。

arr[0][1,2,3,4,0])没有被包括在内,因为arr[0][3] = val = 4arr[1]arr[2]arr[3]都开始[3,4,5]

arr[6][2,3,5,4,6])没有被包括在内,因为arr[6][3] = 4arr[7]arr[8]arr[9]都开始[2,3,5]

arr[2][3,4,5,5,2])已被包括在内,因为,虽然arr[2][3] = 4arr[3][0,3]arr[4][0,3]arr[5][0,3]所有不全部相等(即,arr[5][2] = 0)。

请注意,arr的最后三个元素将始终包含在返回的数组中。

现在让我们来看看计算。首先考虑以下几点。

arr.size 
    #=> 11 

a = (0..arr.size-4).reject { |i| arr[i][3] == val && 
    arr[i+1..i+3].transpose[0,3].map(&:uniq).all? { |a| a.size==1 } } 
    #=> (0..7).reject { |i| arr[i][3] == val && 
    arr[i+1..i+3].transpose[0,3].map(&:uniq).all? { |a| a.size==1 } } 
    #=> [1, 2, 3, 4, 5, 7] 

考虑为i=0(召回val=4reject的块的计算。

arr[i][3] == val && arr[i+1..i+3].transpose[0,3].map(&:uniq).all? {|a| a.size==1 }} 
    #=> 4 == 4 && arr[1..3].transpose[0,3].map(&:uniq).all? { |a| a.size==1 } 
    #=> [[3,4,5,6,1], 
    # [3,4,5,4,2], 
    # [3,4,5,6,3]].transpose[0,3].map(&:uniq).all? { |a| a.size==1 } 
    #=> [[3, 3, 3], 
    # [4, 4, 4], 
    # [5, 5, 5], 
    # [6, 4, 6], 
    # [1, 2, 3]][0,3].map(&:uniq).all? { |a| a.size==1 } 
    #=> [[3, 3, 3], 
    # [4, 4, 4], 
    # [5, 5, 5]].map(&:uniq).all? { |a| a.size==1 } 
    #=> [[3], [4], [5]].all? { |a| a.size==1 } 
    #=> true 

含义arr[0]将被拒绝;即不包括在返回的数组中。 其余的块计算(对于i=1,...,10)是相似的。

我们计算

a #=> [1, 2, 3, 4, 5, 7] 

这是除了最后3将被保留的arr所有元素的索引。到a我们添加arr的最后三个元素的索引。

b = a.concat((arr.size-3..arr.size-1).to_a) 
    #=> a.concat((8..10).to_a) 
    #=> a.concat([8,9,10]) 
    #=> [1, 2, 3, 4, 5, 7, 8, 9, 10] 

最后,

arr.values_at(*b) 

返回在例子中给出的阵列。

相关问题