How can I remove a numerical extension from an array of filenames? - arrays

I want to remove the last 11 characters of strings inside of an array. The array is:
["cool.mp3?3829483927", "wow.mp3?3872947629", "woa.mp3?8392748308"]
I want to convert the strings to this:
["cool.mp3", "wow.mp3", "woa.mp3"]
Is there a method specifically for this in Ruby? I know of chop and chomp, but nothing that can access each string in an array.

TL;DR
There are lots of ways to transform your string, including #slice, #split, #sub, and #partition to name a few. What you're really missing is the Array#map method, which applies a method or block to each element of an array.
Partition Your Filenames
One way to modify your array elements is to map the Enumerable#partition method onto each element, which splits your filenames into an array of components. Ordinarily, this would return an array of arrays where each partitioned string is a sub-array, but you can have the #map block return just the components you want. In this case, what you want is the first element of each partitioned array.
This may sound complicated, but it's actually very simple. For example:
files = ['cool.mp3?3829483927', 'wow.mp3?3872947629', 'woa.mp3?8392748308']
files.map { |filename| filename.partition('?').first }
#=> ["cool.mp3", "wow.mp3", "woa.mp3"]
A Minified Version
If you value compactness over readability, you can get the same result as the solution above with:
files = %w(cool.mp3?3829483927 wow.mp3?3872947629 woa.mp3?8392748308)
files.map { |f| f.partition(??)[0] }
#=> ["cool.mp3", "wow.mp3", "woa.mp3"]

If you want what is before the first '?', do this :
arr.map{|thing| thing.split('?')[0]}

If it's always 11 chars you can do:
arr=["cool.mp3?3829483927","wow.mp3?3872947629", "woa.mp3?8392748308"]
new=arr.map{|thing| thing[0...-11]}

String::slice can take a regex as an argument, so you could extract the names that you want (rather than dropping the last 11 characters):
arr = ["cool.mp3?3829483927","wow.mp3?3872947629", "woa.mp3?8392748308"]
arr.map! {|x| x.slice(/\w+\.mp3/) }
#=> ["cool.mp3", "wow.mp3", "woa.mp3"]

If arr is your array of strings:
arr.map { |s| s[/[^?]+/] }
# => ["cool.mp3", "wow.mp3", "woa.mp3"]
The regular expression /[^?]+/ matches one or more characters that are not (^ at the beginning of the character class) question marks. This uses the methods Array#map and String#[].

Related

Count the number of elements of array that contain a digit

i am new to Ruby and stuck on this exercice. I have this array including string value and i am looking for the number of value including a figure ?
array = ["#jcunniet","#PaulLampon","#Aziliz31","#ssoumier","#marionsouzeau","#gaellombart","#bendarag","#AurelieLebelle","#julienduffe","#thomaspoupeau","#LilyRossignol","#ClairGuedon","#stephanieauguy","#claw_prolongeau","#_JulieMenard","#LColcomb","#Zlauwereys","#MeLonguet","#DorotheeLN","#NolwennCosson","#ADaboval","#Remibaldy","#bderveaux","#amandechap","#ELODIESOULIE","#nbongarcon","#HeloAb","#Panamorama","#gregplou","#BenoitBerthe","#LauraBruneau89","#Anthony_Lieures","#Sharonwaj","#mcsonkin","#pverduzier","#emiliel3","#Julien_MARION","#SophiFay","#bdelombre","#annalecerf","#AdriaBudry","#DejNikolic","#iJaffre","#CyrusleVirus","#GPardigon","#e_vallerey","#IsabelleSouquet","#AudeDavidRossi","#Yoann_Pa","#CeliaPenavaire","#perraultvincent","#cboulate","#JustineWeyl","#Paulinejacot","#juliechab","#aslechevallier","#phnou","#Seb_Pommier","#Alex_Bensaid","#GuillaumeGaven","#annelaurechouin","#Oliviader","#guerricp","#JMMarchaut","#cyceron","#gregory_raymond","#vhunsinger","#l_peillon","#fannyguinochet","#EAssayag","#KibweAdom","#YvonHerry","#JohanGarciajg","#saidlabidi","#lauranneprov","#LeaDavy","#francois_remy","#CGuicheteau","#FloMaillet","#m_perroud","#oBrunet_TSMF","#MoonVdc","#jc2taille","#NellyMoussu","#VirginK","#b_misa","#FabriceCouste","#barbara_prose","#lelia2m","#brunoaskenazi","#laurenechamp","#ysisbox","#juliengagliardi","#PierreLel","#kdeniau","#_TerraInc","#DominicArpin","#antoinfonteneau","#nanotousch","#jb_roch","#YaniKhezzar","#Anne_Bechet","#NCapart","#SamyBenNaceur","#Joumany","#Julietteraynal","#TGiraudet","#SaraTanit","#HappeFrederic","#antoinellorca","#michelpicot","#Sev_Ryne","#bobdobolino","#murdever","#YGrandmontagne","#Mnyo","#EdKOSCIANSKI","#tnoisette","#jankari","#delbello_rom","#rflechaux","#NadiaSorelli","#IT_Digital","#abarbaux","#PhilippeLeroy","#schaptal","#marionspee","#lisavignoli","#ChloeAeberhardt","#MartineJacot","#JuliaPascualita","#curieusedetout","#sgraveleau","#bif_o","#ElisaPineau","#zinebdryef","#apiquard","#pierrehaski","#StephanieDelmas","#Blandine_Garot","#vergara_i","#evan_lebastard","#SophieVclt","#OlivierLevrault","#alicedorgeval","#LouiseMalnoy","#alix_fx","#pierre_baudis","#LucMagoutier","#AgatheMuller","#SGianninelli","#PaulineBoyer33","#NaomiHalll","#romaindlx","#marionbr","#Burtschy","#JacobEtienne","#as_lizzani","#marie_simon","#LaureDaussy","#FabriceAmedeo","#LoubnaChlaikhy","#PlummerWilliam","#OlivierMarin1","#alaurefremont","#mwesfreid","#ChBaDe","#pmathon","#theobaldmarie","#Lnpagesy","#marclandre","#paoliniesther","#Feertchak","#JBLitzler","#GuillaumeErrard","#quentinperinel","#TristanQM","#mlbo","#constancejamet","#LoraTerrazas","#emiliegeffray","#Mathilde_Sd","#CaroPiquet","#DCanivez","#TIM_7375","#blandinelc","#ivanrioufol","#arthurberdah","#SarahLecoeuvre","#guillaume_gui","#DamienMercereau","#W_Chloe","#Assma_MD","#EugenieBastie","#HiTech_lexpress","#bcondominas","#Laurie_Z_","#jeanfrancgerard","#MathieuPagura","#BGUYF","#AlainPiffaretti","#AudreyKucinskas","#julienhory","#Pierrefalga","#TiphThuillier","#cdaniez","#LigerBaptiste","#D_Peras","#julie_dlb","#Fatiha_Temmouri","#julian2lamancha","#GaetaneDeljurie","#JulianMattei","#M_Vicuna","#DeBruynOlivier","#Nehed_Jendoubi","#antoine_grenapi","#ColonnaGen","#VictoriaGairin","#Clement_Lacombe","#TVigoureux","#MargauxObriot","#solinedelos","#RocheSabine","#dangerkens","#EdouardDutour","#MDondeyne","#DupuisNathalie1","#bouscarel","#Mathieu2jean","#Sophie_T_J","#laurentcalixte","#patrockwilliams","#PascaleKremer","#AlexJaquin","#LauraIsaaz","#cath_robin","#Del_Gautherin","#Isaduriez","#lucietuile","#AugeyBastien","#mcastagnet","#AminaKalache","#mvaudano","#CParrot","#ombelinetips","#_JoinLion","#BarbolosiRose","#ToiBruno1","#FloraClodic","#xjbdx","#AlexiaEy","#Emjy_STARK","#elcoco01","#rabilebon","#pflovens_","#FabriceFrossard","#MorganeSERRES","#MarjolaineKoch","#edgarsnow","#SRNLF","#CChassigneux","#KerinecMoran","#NassiraELM","#NewsRicard","#Sandreene","#Emilezrt","#Pierre_Do","#Micode","#CColumelli","#DavidAbiker","#ClementBergantz","#benjaminrabier","#celinekallmann","#edwyplenel","#C_Barbier","#JJBourdin_RMC","#LaurenceFerrari","#aslapix","#IsaMillet","#MaximeSwitek","#tomjoubert","#jszanchi","#roqueeva","#XavierBiseul","#florencesantrot","#AntoineCrochet","#freeman59","#MaudeML","#philippe_gulpi","#mathieum76","#kiouari","#imanemoustakir","#BenedicteMallet","#Emilie_Brouze","#antoinebarret","#_nicolasbocquet","#remibuhagiar","#CourretB","#AymericRobert","#miraelmartins","#pmaniere","#jesuisraphk","#David_Ingram","#pcelerier","#technomedia","#Geraldinedauver","#ThierryLabro","#Newsdusud","#nrauline","#gbregeras","#SCouasnonBFM","#actualites_nrv","#dimitrimoulins","#oli_aura","#FabieChiche","#Vincent_Raimblt","#ChristophGreuet","#PAlbuchay","#MarrauddesGrot","#vtalmon","#cedric","#olivierfrigara","#Julien_Jay","#LydiaBerroyer","#Shuua","#datisdaz","#Steuph","#ameliecharnay","#Bruno_LesNums","#LelloucheNico","#CciliaDiQuinzio","#Elodie_C","#SylvRolland","#Kocobe","#FL_Debes","#jdupontcalbo","#GarciaVictor_","#NicoRichaud","#RHoueix","#simottel","#DamienLicata","#annabelle_L","#Lea_Lejeune","#axel_deb","#marin_eben","#ptiberry","#MatthieuDelach","#sandrinecassini","#benjaminferran","#ppgarcia75","#NotPatrick","#ivalerio","#FabienneSchmitt","#alexgoude","#JeromeColombain","#manhack","#Capucine_Cousin","#Fsorel","#oliviertesquet","#marjoriepaillon","#ginades","#PierreTran","#DelphineCuny","#reesmarc","#lauratenoudji","#ldupin","#carolinedescham","#Lucile_Quillet","#cgabizon","#Allocab","#epenser","#JAGventeprivee","#frwrds","#Laure__Bourdon","#Xavier75","#maximeverner","#s_jourdain","#LoriHelloc"]
i = 0
array.each do |n|
if n.include?("1,2,3,4,5,6,7,8,9,10")
then i += 1
end
puts i
end
Do you mean something like this?
array.grep(/[1-9]/).count
Edit: Changed regEx from /[1-10]/ to /[1-9]/
Often code that is the direct translation of the question is best: “Count the number of elements of array that contain a digit”.
array.count { |s| s.match? /\d/ }
See Array#count and String#match?.

Ruby Iterating Through Array for Method Names

I have an object that I want to output a bunch of methods' results from. I have an array of method names and want to iterate through them:
img = Magick::Image::read('/Users/rich/Projects/imagemagick/orig/IMG_4677.jpg')[0]
atts = "background_color base_columns base_filename base_rows bias black_point_compensation".split(' ')
atts.each do |i|
puts img.i # problem evaluating i
end
I have tried string interpolation and eval but I can't get it to realize it's a method call.
Is there a way I can apply an array as method names to an object?
Try using public_send:
atts = "upcase downcase".split
atts.each do |i|
puts 'hEllO'.public_send(i)
end
#HELLO
#hello

Ruby - elegantly flatten an array but don't ignore empty sub-arrays

Using .flatten is a handy little trick to take an array of sub-arrays and turn it into a single array.
For example: [[1,3],2,[5,8]].flatten => [1,3,2,5,8]
You can even include nil [1,[2,nil],3].flatten will result in [1,2,nil,3].
This kind of method is very useful when nesting a .map method, but how would you account for an empty sub-array? For example: [1,[2,3],[],4].flatten would return [1,2,3,4]... but what if I need to keep track of the empty sub array maybe turn the result into [1,2,3,0,4] or [1,2,3,nil,4]
Is there any elegant way to do this? Or would I need to write some method to iterate through each individual sub-array and check it one by one?
If you don't need to recursively check nested sub-arrays:
[1,[2,3],[],4].map { |a| a == [] ? nil : a }.flatten
First map the empty arrays into nils, then flatten
[1,2,[1,2,3],[]].map{|x| if x.is_a? Array and x.empty? then nil else x end}.flatten

How do I split on a regex and get my elements into an array?

I'm using Ruby 2.4. Is there any way I can split on a regex and get the resulting elements in an array? I thought this was the way
2.4.0 :003 > word = "4.ARTHUR"
=> "4.ARTHUR"
2.4.0 :004 > word.split(/^\d+\./)
=> ["", "ARTHUR"]
but as you see, the first element of my array is an empty string despite the fact that the pattern matches. I would like the output to be
["4.", "ARTHUR"]
Note that split splits the string where a match is found. So, ^\d+\. matches 4. in 4.ARTHUR at the beginning and thus, the result is an empty string (the beginning of the string) and ARTHUR. To keep the match obtained during split operation with a regex, you need to wrap the whole pattern with a capturing group and to get rid of the empty items, you can just remove them later:
word.split(/^(\d+\.)/).reject { |x| x.empty? }
Why not just do
irb(main):004:0> word = "4.ARTHUR"
=> "4.ARTHUR"
irb(main):005:0> word.split('.')
=> ["4", "ARTHUR"]
When you want to split up a string but keep all of its parts, String#scan is often a better fit than String#split:
word = "4.ARTHUR"
word.scan(/^\d+\.|.+/)
# => ["4.", "ARTHUR"]
See it on repl.it: https://repl.it/F90q
Try this
a, b = word.match(/^(\d+\.)?(.*)/).captures
The split method is meant to be used with a separator, as for example a comma. What you are doing is splitting the string into two parts without a separator, just use capture groups.

Take two arrays of strings and return an array with the combinations of the items in them

I need to take two arrays and return a single array with the combination of the items in them, listing the first items first. Like so:
combinations(["on","in"],["to","rope"])
# => ["onto","onrope","into","inrope"]
I've written a method that does this, but after that, I can't figure out where to go.
Use Array#product:
["on","in"].product(["to","rope"]).map(&:join)
# => ["onto", "onrope", "into", "inrope"]
def combinations(ary1, ary2)
ary1.map {|i| ary2.map {|i2| "#{i}#{i2}" }}.flatten
end

Resources