2010-02-13 7 views
7

En Ruby, je voudrais convertir un String slash-distinct tel que "foo/bar/baz" dans ["foo/bar/baz", "foo/bar", "foo"]. J'ai déjà des solutions de quelques lignes de long; Je suis à la recherche d'un one-liner élégant. Il doit également travailler pour des nombres arbitraires de segments (0 et plus).Le moyen le plus simple de convertir "a/b/c" en ["a/b/c", "a/b", "a"]

+2

Vous ne connaissez 'FileUtils.mkdir_p', n'est-ce pas? – Svante

Répondre

4

Les plus annotées des œuvres de réponse, mais voici un peu plus court moyen de le faire que je pense que ce sera plus facile à lire pour ceux qui ne connaissent pas toutes les fonctionnalités qui y sont utilisés:

a=[]; s.scan(/\/|$/){a << $`} 

Le résultat est enregistré dans a:

> s = 'abc/def/ghi' 
> a=[]; s.scan(/\/|$/){a << $`} 
> a 
["abc", "abc/def", "abc/def/ghi"] 

Si l'ordre est important, vous pouvez inverser le tableau ou utiliser unshift au lieu de <<.

Merci à dkubb, et à l'OP pour les améliorations apportées à cette réponse.

+0

Sur ruby ​​1.8.7 le résultat est seulement # => "abc/def/ghi" et non le tableau comme spécifié dans la réponse – nas

+2

@nas: La valeur de retour sera la chaîne dans n'importe quelle version de ruby. Le tableau demandé sera dans la variable 'a'. Si vous étiez au courant de cela et que vous étiez en train de cogner, n'hésitez pas à ignorer mon commentaire. – sepp2k

+2

Vous pouvez simplifier le code dans le bloc en procédant comme suit: a = []; 'abc/def/ghi'.scan (/ \/| $ /) {a << $ '} – dkubb

12
"foo/bar/baz".enum_for(:scan, %r{/|$}).map {Regexp.last_match.pre_match} 
+0

'Enumérateur' FTW! –

+0

Wow. C'est presque du lisp sans toutes les parens. –

+0

bon! Code plus facile "foo/bar/baz" .enum_for (: scan,% r {/ | $}). Map {$ '} – user3673267

0

Pas tout à fait aussi efficace que la réponse choisie et donne [] quand donné une chaîne vide, plutôt que [""], mais son un vrai paquebot: P

s.split('/').inject([]) { |a,d| a.unshift([a.first,d].compact.join('/')) } 
0
->(l,s,z){ 
    (t = s[/#{z}.[^\/]*/]) && [l[l,s,t], t] 
}.tap{ |l| 
    break l[l,'a/b/c',''] 
}.flatten.compact 
+0

Oups, ce n'est pas le plus simple ... – Nakilon

Questions connexes