2016-06-17 66 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) 

返回在例子中給出的陣列。

相關問題