2015-11-10 3 views

ответ

5

Вы можете использовать Array#map метод:

foo = bars.map(&:some_rel) 

что эквивалентно:

foo = bars.map { |bar| bar.some_rel } 
1

Можно, как в Python, чтобы создать массив из цикла в только одна строка? Могу ли я сделать следующий код в одной строке?

foo = [] 
bars.each do |bar| foo.append(bar.some_rel) end 

Я никогда не понять, что одержимость с делать что-то в одной строке, но, да, в Ruby, вы можете создать массив из цикла только в одной строке. На самом деле, в Ruby вы можете сделать все в одной строке. Просто замените все переносы строк с запятой:

foo = []; bars.each do |bar| foo.append(bar.some_rel) end 

Например, это фреймворк называется Camping:

require"uri";require"rack";class Object;def meta_def m,&b;(class<<self;self end).send:define_method,m,&b end end;module Camping;C=self;S=IO.read(__FILE__)rescue nil;P="<h1>Cam\ping Problem!</h1><h2>%s</h2>";U=Rack::Utils;O={};Apps=[];SK=:camping;class H<Hash;def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.to_s]:super end;undef id,type if ??==63 end;class Cookies<H;attr_accessor :_p;def _n;@n||={}end;alias _s []=;def set k,v,o={};_s(j=k.to_s,v);_n[j]={:value=>v,:path=>_p}.update o;end;def []=(k,v)set(k,v,v.is_a?(Hash)?v:{})end end;module Helpers;def R c,*g;p,h=/\(.+?\)/,g.grep(Hash);g-=h;raise"bad route"if !u=c.urls.find{|x|break x if x.scan(p).size==g.size&&/^#{x}\/?$/=~(x=g.inject(x){|x,a|x.sub p,U.escape((a.to_param rescue a))}.gsub(/\\(.)/){$1})};h.any?? u+"?"+U.build_query(h[0]):u end;def/p;p[0]==?/[email protected]+p :p end;def URL c='/',*a;c=R(c,*a) if c.respond_to?(:urls);c=self/c;[email protected][/.{8,}?(?=\/|$)/]+c if c[0]==?/;URI c end end; module Base;attr_accessor:env,:request,:root,:input,:cookies,:state,:status,:headers,:body;T={};L=:layout;def lookup n;T.fetch(n.to_sym){|k|t=Views.method_defined?(k)||(t=O[:_t].keys.grep(/^#{n}\./)[0]and Template[t].new{O[:_t][t]})||(f=Dir[[O[:views]||"views","#{n}.*"]*'/'][0])&&Template.new(f,O[f[/\.(\w+)$/,1].to_sym]||{});O[:dynamic_templates]?t: T[k]=t} end;def render v,*a,&b;if t=lookup(v);[email protected]_r;@_r=o=Hash===a[-1]?a.pop: {};s=(t==true)?mab{send v,*a,&b}: t.render(self,o[:locals]||{},&b);s=render(L,o.merge(L=>false)){s}if o[L]or o[L].nil?&&lookup(L)&&!r&&v.to_s[0]!=?_;s;else;raise"no template: #{v}"end;end;def mab &b;extend(Mab);mab(&b) end;def r s,b,h={};b,h=h,b if Hash===b;@status=s;@headers.merge!(h);@body=b end;def redirect *a;r 302,'','Location'=>URL(*a).to_s end;def r404 p;P%"#{p} not found"end;def r500 k,m,e;raise e end;def r501 m;P%"#{m.upcase} not implemented"end;def serve(p,c)(t=Rack::Mime.mime_type p[/\..*$/],"text/html")&&@headers["Content-Type"]=t;c;end;def to_a;@env['rack.session'][SK]=Hash[@state];r=Rack::Response.new(@body,@status,@headers);@cookies._n.each{|k,v|r.set_cookie k,v};r.to_a end;def initialize(env,m)[email protected]=Rack:: Request.new(@env=env);@root,@input,@cookies,@state,@headers,@status,@method=r.script_name.sub(/\/$/,''),n(r.params),Cookies[r.cookies],H[r.session[SK]||{}],{'Content-Type'=>'text/html'},m=~/r(\d+)/?$1.to_i: 200,m;@cookies._p=self/"/" end;def n h;Hash===h ?h.inject(H[]){|m,(k,v)|m[k]=n(v);m}: h end;def service *a;r=catch(:halt){send(@method,*a)};@body||=r;self end end;module Controllers;@r=[];class<<self;def R *u;[email protected];Class.new{meta_def(:urls){u};meta_def(:inherited){|x|r<<x}}end;def D p,m,e;p='/'if !p||!p[0];(a=O[:_t].find{|n,_|n==p}) and return [I,:serve,*a];@r.map{|k|k.urls.map{|x|return(k.method_defined? m)?[k,m,*$~[1..-1].map{|x|U.unescape x}]:[I, 'r501',m]if p=~/^#{x}\/?$/}};[I,'r404',p] end;N=H.new{|_,x|x.downcase}.merge!("N"=>'(\d+)',"X"=>'([^/]+)',"Index"=>'');def M;def M;end;constants.map{|c|k=const_get(c);k.send:include,C,X,Base,Helpers,Models;@r=[k][email protected] if @r-[k][email protected];k.meta_def(:urls){["/#{c.to_s.scan(/.[^A-Z]*/).map(&N.method(:[]))*'/'}"]}if !k.respond_to?:urls}end end;I=R()end;X=Controllers;class<<self;def goes m,g=TOPLEVEL_BINDING;Apps<<a=eval(S.gsub(/Camping/,m.to_s),g);caller[0]=~/:/;IO.read(a.set:__FILE__,$`)=~/^__END__/&&(b=$'.split /^@@\s*(.+?)\s*\r?\n/m).shift rescue nil;a.set :_t,H[*b||[]];end;def call e;X.M;k,m,*a=X.D e["PATH_INFO"],e['REQUEST_METHOD'].downcase,e;k.new(e,m).service(*a).to_a;rescue;r500(:I,k,m,$!,:env=>e).to_a end;def method_missing m,c,*a;X.M;h=Hash===a[-1]?a.pop: {};e=H[Rack::MockRequest.env_for('',h.delete(:env)||{})];k=X.const_get(c).new(e,m.to_s);h.each{|i,v|k.send"#{i}=",v};k.service(*a) end;def use*a,&b;m=a.shift.new(method(:call),*a,&b);meta_def(:call){|e|m.call(e)}end;def options;O end;def set k,v;O[k]=v end end;module Views;include X,Helpers end;module Models;autoload:Base,'camping/ar';Helpers.send:include,X,self end;autoload:Mab,'camping/mab';autoload:Template,'camping/template';C end 

См? Одна линия!

+0

«Я никогда не понимаю, что такое навязчивая идея с помощью чего-то в одной строке». Читаемость. 'foo = bars.map (&: some_rel)' просто красиво. –

+0

Но это не происходит из-за того, что он написан на одной строке. Он исходит из использования идиоматических Ruby, абстракций высокого уровня и хорошего объектно-ориентированного дизайна. Вы находите [это] (https://github.com/camping/camping/blob/master/lib/camping-unabridged.rb) более читаемым или версию, которую я опубликовал в своем ответе? Это * точный идентичный * код, за исключением того, что все строки были удалены и, таким образом, написаны на одной строке. Вы утверждаете, что однострочная версия более читаема, я не согласен. –

+0

Нет, я этого не делаю. Но создание массива из цикла - это то, что вы делаете много. Узнав об этом, вы сразу поймете, что он делает. Короче говоря, он быстрее читает и понимает. По крайней мере, так оно и есть для меня. –

0

Возможно ли, как и в Python, создать массив из цикла только в одной строке?

Ruby позволит вам делать все, что угодно, в любом количестве строк.

Если вы хотите, просто положите полуточку в конце каждой строки, и вы можете написать каждое утверждение в той же строке.

Если вы используете одну строку для Array#each, вы должны использовать { и } в качестве разделителей блоков. Это не имеет большого значения; это просто лучшая практика.

С Array#each, вы не можете сделать:

foo = bar.each{|x| x.some_rel} 

Это потому, что Array#eachвсегда возвращается nil.

Как и в другом ответе, для ваших целей вы можете использовать Array#map, потому что #map возвращает массив. Таким образом, вы можете сделать это:

foo = bar.map{|x| x.some_rel} 

Потому что mapвозвращает что-то.

Это будет в одной строке.Если вы действительно хотите излишеством, вы можете написать всю программу в одну строку следующим образом:

foo = []; foo.do_something; foo.do_something_else; bar.whatever; 

Но это выглядит некрасиво и не будет читаемым. Ruby - все о удобочитаемости.

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