2014-10-02 2 views
1

У меня есть массив массивов, содержащих объекты:Проверьте массив уже содержит новый набор, независимо от того,

[ [A, B, C], 
    [A, B, D], 
    [B, C, D] ] 

Я хочу, чтобы проверить, что значение как [B, A, C] не может быть добавлен, так как это не является уникальным для моих целей , Существующие массивы в массиве не должны иметь дубликатов (я уже обрабатываю это).

Я попытался следующий код, но он не работает:

#if false, don't add to existing array 
!big_array.sort.include? new_array.sort 

Что я делаю неправильно?

+0

'# sort' сортирует объект, но не объекты в стороне, вы можете использовать' map (&: sort) ', который будет сортировать массивы внутри. – engineersmnky

+0

Я ценю зеленый знак, ММ, но в будущем я бы посоветовал вам отложить выбор ответа, чтобы вы не отговаривали других участников (с возможными лучшими ответами) или не вытесняли кого-то, кто все еще работал над своим ответом. –

ответ

1
require 'set' 

a = [['a', 'b', 'c'], 
    ['a', 'b', 'd'], 
    ['b', 'c', 'd']] 

as = a.map(&:to_set) 

as.include? ['b', 'a', 'c'].to_set #=> true 
as.include? ['b', 'a', 'e'].to_set #=> false 

Использование:

(as << row.to_set) unless as.include? row.to_set 

тогда, когда закончил:

as.to_a 

Учитывая свой комментарий, если вы добавите все строки к:

a = [['a', 'b', 'c'], 
    ['a', 'b', 'd'], 
    ['b', 'c', 'd'], 
    ['a', 'c', 'b'], 
    ['c', 'a', 'b'], 
    ['e', 'a', 'b'], 
    ['c', 'b', 'd']] 

затем:

a.reverse 
.map(&:to_set) 
.uniq 
.map(&:to_a) 
    #=> [["b", "c", "d"], 
    # ["e", "a", "b"], 
    # ["a", "b", "c"], 
    # ["a", "b", "d"]] 

reverse необходимо сохранить исходные массивы, но обратите внимание, что порядок не сохраняется в результате. Если вы хотите сохранить порядок модифицированного a:

a.each_with_object(Set.new) { |row,set| set << row.to_set } 
.map(&:to_a) 
    #=> [["a", "b", "c"], 
    # ["a", "b", "d"], 
    # ["b", "c", "d"], 
    # ["e", "a", "b"]] 
+0

Просто добавьте to_set и это, если оператор не работает для меня без каких-либо изменений. Похоже, что замедление было немного, хотя, возможно, было бы быстрее отфильтровать их после факта, а не проверять основной массив каждый раз, когда мы будем нажимать на него. –

1

Вы должны сортировать массивы внутри своего большого массива. Не большой массив сам

!big_array.map(&:sort).include? new_array.sort 
+0

У меня все еще возникают проблемы с этим, я думаю, что моя программа настроена. Изначально big_array = [], затем, когда я прохожу через петлю, я вставляю в нее другие массивы. С этим кодом он в настоящее время принимает все. Думаю, мне может понадобиться распрям? –

+0

Являются ли другие массивы двумерными? Если это так, вам нужно будет сгладить каждый элемент внутри big_array. – usha

+0

Только большой массив двухмерен. –

0
a = [ 
    ['a', 'b', 'c'], 
    ['a', 'b', 'd'], 
    ['b', 'c', 'd'] 
] 

class Array 
    def add_only_if_combination_does_not_exist_in(double_array) 
    if double_array.map(&:sort).include?(self.sort) 
     puts "Won't be added since it already exists!" 
    else 
     puts 'Will be added' 
     double_array << self 
    end 
    end 
end 

['b', 'a', 'c'].add_only_if_combination_does_not_exist_in(a) 
['b', 'a', 'f'].add_only_if_combination_does_not_exist_in(a) #=> Will be added 
p a #=> [["a", "b", "c"], ["a", "b", "d"], ["b", "c", "d"], ["b", "a", "f"]] 
0

Если вы не заботитесь о порядке элементов, рассмотреть вопрос об использовании Set класса.

require 'set' 

big_set = Set.new 

big_set << Set.new(['a', 'b', 'c']) 
# => #<Set: {#<Set: {"a", "b", "c"}>}> 

big_set << Set.new(['c', 'b', 'a']) 
# => #<Set: {#<Set: {"a", "b", "c"}>}> 

big_set << Set.new(['d', 'a', 'b']) 
# => #<Set: {#<Set: {"a", "b", "c"}>, #<Set: {"d", "a", "b"}>}> 
Смежные вопросы