Я бы рекомендовал использовать PDO (объекты данных PHP) для запуска параметризованных SQL-запросов.
Это не только защищает от SQL-инъекции, но и ускоряет выполнение запросов.
И используя функции PDO, а не mysql_
, mysqli_
и pgsql_
, вы делаете свое приложение немного более абстрактным из базы данных, в редких случаях, когда вам нужно переключать поставщиков баз данных .
Если Вы действительно хотите, можно создать метод Array#comprehend как это:
class Array
def comprehend(&block)
return self if block.nil?
self.collect(&block).compact
end
end
some_array = [1, 2, 3, 4, 5, 6]
new_array = some_array.comprehend {|x| x * 3 if x % 2 == 0}
puts new_array
Печать:
6
12
18
я, вероятно, просто сделал бы это способ, которым Вы сделали все же.
Как насчет:
some_array.map {|x| x % 2 == 0 ? x * 3 : nil}.compact
Немного инструмент для очистки, по крайней мере, к моему вкусу, и согласно быстрому эталонному тестированию приблизительно на 15% быстрее, чем Ваша версия...
Я думаю, что наиболее подходящим для понимания списков будет следующее:
some_array.select{ |x| x * 3 if x % 2 == 0 }
Поскольку Ruby позволяет нам помещать условное выражение после выражения, мы получаем синтаксис, аналогичный версии Python для понимания списка . Кроме того, поскольку метод select
не включает ничего, что приравнивается к false
, все значения nil удаляются из результирующего списка, и не требуется вызова функции compact, как в случае, если бы мы использовал вместо этого карту
или collect
.
Я обсуждал эту тему с Рейном Хенриксом, который сказал мне, что наиболее эффективным решением является
map { ... }.compact`
Это имеет смысл, потому что оно избегает создания промежуточных массивов, как при неизменном использовании Enumerable#inject
, и это позволяет избежать роста Массива, что вызывает выделение. Он так же общий, как и любой другой, если ваша коллекция не может содержать нулевых элементов.
Я не сравнивал это с
select {...}.map{...}
Возможно, что реализация Ruby на C Enumerable#select
также очень хороша.
[1, 2, 3, 4, 5, 6].collect{|x| x * 3 if x % 2 == 0}.compact
=> [6, 12, 18]
У меня это работает. Это тоже чисто. Да, это то же самое, что и map
, но я думаю, что collect
делает код более понятным.
select(&:even?).map()
действительно выглядит лучше, после того, как увидит это ниже.
Как упоминал Педро, вы можете объединить связанные вызовы в Enumerable # select
и Enumerable # map
, избегая обхода выбранных элементов. Это верно, потому что Enumerable # select
является специализацией свертки или inject
. Я опубликовал поспешное введение в эту тему в сабреддите Ruby.
Объединение преобразований массива вручную может быть утомительным, так что, возможно, кто-нибудь сможет поиграть с реализацией Роберта Гэмбла понять
, чтобы сделать этот select
/ паттерн map
красивее.
Это более лаконично:
[1,2,3,4,5,6].select(&:even?).map{|x| x*3}
Альтернативное решение который будет работать в каждой реализации и запускаться за O (n) вместо O (2n). Время:
some_array.inject([]){|res,x| x % 2 == 0 ? res << 3*x : res}