2014-01-29 3 views
0

У меня есть массив, который выглядит как этотУдалить дубликаты и удалить ненужные строки в массиве

@arr_sh = ['JAN 28, 2014','JAN 21, 2014', 'RATE THIS MOVIE', 'MOVIE INFO', 'WATCH IT NOW', 'JAN 14, 2014', 'RATE THIS MOVIE', 'MOVIE INFO', 'WATCH IT NOW', 'JAN 7, 2014', 'RATE THIS MOVIE', 'MOVIE INFO', 'WATCH IT NOW', 'DEC 31, 2013', 'DEC 24, 2013', 'DEC 17, 2013', 'RATE THIS MOVIE', 'MOVIE INFO', 'WATCH IT NOW'] 

Как вы можете видеть, что повторение «Оценить этот MOVIE» Данные «MOVIE INFO», «WATCH IT NOW»

Я пробовал @arr_sh.uni q и я до сих пор вижу повторяющиеся значения.

Вопрос 1. Как удалить дубликаты в этом массиве 2. И затем я хочу создать отдельный массив со значениями только дат из этого массива @arr_sh. так что новый массив должен выглядеть

@arr_date = ['JAN 28, 2014','JAN 21, 2014', 'JAN 14, 2014', 'JAN 7, 2014', 'DEC 31, 2013', 'DEC 24, 2013', 'DEC 17, 2013'] 

Я использую Ruby, 1.9.3

+0

'@ arr_sh.uniq' будет правильно удалять дубликаты, но не будет изменять массив на месте. Используйте '@ arr_sh.uniq!', Чтобы на самом деле мутировать массив, хранящийся в '@ arr_sh'. –

+0

Чтобы сохранить только даты в массиве. Вы можете использовать @ arr_sh.delete_if {| i | [«Оцените этот фильм», «ИНФОРМАЦИЯ О ВИДЕО», «ПОСМОТРЕТЬ ТЕПЕРЬ СЕЙЧАС»]. Включите? (I)} – vidaica

+0

@vidaica, вы должны квалифицировать свое предложение, так как вы предполагаете, что '@ arr_sh' никогда не содержит ничего, кроме дат выраженные в виде строк и заглавных строк, которые вы хотите исключить. –

ответ

1

Во-первых вам нужно использовать .uniq!, если вы хотите, чтобы мутировать массив на месте. Вы можете использовать класс Date разобрать ваши даты (предложение mudasobwa в)

irb(main):007:0> @arr_sh.uniq.select {|v| Date.parse(v) rescue false} 
=> ["JAN 28, 2014", "JAN 21, 2014", "JAN 14, 2014", "JAN 7, 2014", "DEC 31, 2013", "DEC 24, 2013", "DEC 17, 2013"] 
irb(main):008:0> new_arr = @arr_sh.uniq.select {|v| Date.parse(v) rescue false} 
=> ["JAN 28, 2014", "JAN 21, 2014", "JAN 14, 2014", "JAN 7, 2014", "DEC 31, 2013", "DEC 24, 2013", "DEC 17, 2013"] 
+0

Регулярное значение более подходит для выбора. Это будет нормально: '[AZ] {3} \ s [0-9] {1,2} \, \ s [0-9] {4}' – Sergey

+0

Это означает, что вы в зависимости от его дат всего 3 письма за месяц и 4 номера за год. Шахта просто зависит от того, что его даты были единственной с запятой. И почему бы и нет, если он будет следовать тому же стилю, который он показывает выше. – snowe

+0

Если вы действительно хотите, чтобы это было лучше, это сработало бы лучше. '\ w + \ s \ d +, \ s \ d +' – snowe

0

Чтобы удалить точно дубликаты (не значение, содержащее что-то конкретное) просто использовать код:

@arr_sh.select{ |v| @arr_sh.select{|u| u == v }.size == 1 } 
# => ["JAN 28, 2014", "JAN 21, 2014", "JAN 14, 2014", "JAN 7, 2014", "DEC 31, 2013", "DEC 24, 2013", "DEC 17, 2013"] 
0

Это выполняет то, что вы хотите лаконично:

@arr_date = @arr_sh.uniq!.select{|str| str =~ /\A[A-Z]{3} \d{2}, \d{4}\z/ } 

Что дает

p @arr_sh 
#=> ["JAN 28, 2014", "JAN 21, 2014", "RATE THIS MOVIE", "MOVIE INFO", "WATCH IT NOW", "JAN 14, 2014", "JAN 7, 2014", "DEC 31, 2013", "DEC 24, 2013", "DEC 17, 2013"] 

p @arr_date 
#=> ["JAN 28, 2014", "JAN 21, 2014", "JAN 14, 2014", "DEC 31, 2013", "DEC 24, 2013", "DEC 17, 2013"] 
+0

Поскольку вы использовали 'uniq!' '@ Arr_sh', он никогда не будет таким :-) – mudasobwa

+0

У меня сложилось впечатление, что это намерение napsterdsilva, но да, это важно иметь в виду. – jkrmr

+0

Я имел в виду, что вы отвечаете, что сейчас неверно: 'p @ arr_sh' не будет содержать' 'RATE THIS MOVIE '' - как дерьмо. – mudasobwa

0

Редактировать: @ snowe2010 указал, что мой ответ очень похож на его, который он опубликовал ранее. Это правда, и я извинился за то, что не упоминал об этом, но в свою защиту я почему-то не заметил его ответа. Однако я оставлю все, так как некоторые из моих замечаний могут быть полезны для напстердильвы, которая, вероятно, довольно нова для Руби.

Я думаю, что вам нужно сделать что-то вроде этого, чтобы извлечь дату и больше ничего:

require 'date' 

dates = @arr_sh.select do |str| 
    begin 
    Date.strptime(str, '%b %d, %Y') 
    true 
    rescue ArgumentError 
    false 
    end 
end 
dates # => ["JAN 28, 2014", "JAN 21, 2014", "JAN 14, 2014", "JAN 7, 2014", 
     #  "DEC 31, 2013", "DEC 24, 2013", "DEC 17, 2013"] 

К сожалению, Ruby не имеет метод is_a_date?(str, '%b %d, %Y'). Вместо этого вы просто должны позволить Date#strptime вызывать исключение, когда он задыхается. Если strptime возвращает объект даты, то выполняется true и возвращается к select; else добавляется ArgumenError, который улавливается предложением rescue, а false возвращается в select, а затем на следующий объект str.

Это отклонит «Моя собака называется Diva», но она также отвергает «JAN 99, 2014» и «FEB 29, 2014», которые могут проскальзывать с помощью более простых фильтров. Он также отклонит «28 января 2014 года», что-то, чего вы не можете захотеть, но в этом случае вам, вероятно, необходимо сначала обеспечить, чтобы все даты имели общий формат.

Возможно, вы думаете, что это ужасная проблема, просто чтобы убедиться, что строка - это дата. Да, это боль, но я думаю, что что-то вроде этого ожидалось бы в производственной среде, где стоимость несанкционированного уклонения от вашего фильтра может быть очень высокой.

Возможно, вы захотите рассмотреть возможность хранения объектов даты, а не строк даты. Это позволит вам легко манипулировать и сравнивать даты.Ваша проблема здесь упростится:

dates = @arr_sh.select { |e| e.class == Date } 
+0

Это почти точно мой ответ, за исключением использования strptime. – snowe

+0

@snowe, я прошу прощения за то, что не упомянул о вашем ответе. Я исправил это. –

+0

Я не пытался быть злым, я просто подумал, что хочу указать на это. И да, ваш ответ гораздо более глубокий, чем мой. – snowe

Смежные вопросы