2

I'm trying to make a array out of a string and then get rid of the quotes surrounding the strings.

This is what I tried:

hg = "'Erra', 'Erra-Network', 'Discovery'".split(",")
hg2 = hg.each { |n| n.delete_prefix("'").delete_suffix("'") }
print(hg2)

but doesn't work.

Output:

["'Erra'", " 'Erra-Network'", " 'Discovery'"]
EarlGrey
  • 2,514
  • 4
  • 34
  • 63
  • what is the expected output? – lacostenycoder Feb 05 '20 at 14:13
  • an array without the single quotes – Mefistofeles Feb 05 '20 at 14:19
  • change `each` to `map` and try again – quetzalcoatl Feb 05 '20 at 14:20
  • `"'Erra', 'Erra-Network', 'Discovery'"` – where does that string come from? – Stefan Feb 05 '20 at 14:45
  • @Mefistofeles : You calculate inside your block a new string, and then throw it away. You never actually modify one of the array elements. Look up in the docs the difference between `delete_prefix` and `delete_prefix!`. – user1934428 Feb 05 '20 at 14:50
  • Rather than splitting the string, then removing the quotes from each element of the resulting array it makes more sense to remove the quotes from the string before splitting it. If `str = "'Erra', 'Erra-Network', 'Discovery'"`, then `str.delete("'").split(", ") #=> ["Erra", "Erra-Network", "Discovery"] `. If there may be zero or two or more spaces after each comma, write `str.delete("'").split(/, */)`. The regular expression `/, */` reads, "match a comma followed by zero or more (`*`) spaces". – Cary Swoveland Feb 05 '20 at 17:14
  • Please don't say things like "doesn't work." We need to know _WHY_ it doesn't. If you don't tell us we sometimes can guess, but too often the reason is because it doesn't meet your needs/goals and we have no idea what those are. Please see "[ask]", "[Stack Overflow question checklist](https://meta.stackoverflow.com/questions/260648)" and "[MCVE](https://stackoverflow.com/help/minimal-reproducible-example)" and all their linked pages. – the Tin Man Feb 05 '20 at 17:41
  • Your string is suspicious. We rarely see strings like that if we've handled our input right. I suspect this is an XY problem where you're asking about the wrong thing; you should be asking about how to properly gather the data prior to needing to clean it and parse it. See "[What is the XY problem?](https://meta.stackexchange.com/a/66378/153968)". – the Tin Man Feb 05 '20 at 18:32

4 Answers4

4

Try map instead of each, it will return a new updated Array:

hg = "'Erra', 'Erra-Network', 'Discovery'".split(",")
hg2 = hg.map { |n| n.delete_prefix("'").delete_suffix("'") }
print(hg2)

each will execute for each element in the Array, but will then return the original unmodified Array. map actually returns the modified Array: https://stackoverflow.com/a/5254192/44733

Martin Owen
  • 5,221
  • 3
  • 35
  • 31
1

You're working on hg but then printing hg2 to check if the operation succeeded. Although that's not the problem, it may lead to confusion.

Also, as you're using delete_prefix and delete_suffix in their non-destructive versions, the changes applied return a new object, which isn't "persisted" anywhere.

If you want to see the changes that that produces you can use their destructive version delete_prefix!, delete_suffix!:

hg2 = hg.each do |n|
  n.delete_prefix!("'")
  n.delete_suffix!("'")
end

hg # ["Erra", " 'Erra-Network", " 'Discovery"]

Or rather use map and yield the result of every operation into a new object:

hg2 = hg.map { |n| n.delete_prefix("'").delete_suffix("'") }

p hg2 # ["Erra", " 'Erra-Network", " 'Discovery"]

Although this results in ["Erra", " 'Erra-Network", " 'Discovery"] and doesn't go according to the title of the question "delete the quotes surrounding the strings".

Sebastián Palma
  • 32,692
  • 6
  • 40
  • 59
  • Aaah I got it, totally. – Sebastián Palma Feb 05 '20 at 14:47
  • As per the last comment, the title is a bit misleading as it doesn't correspond itself with what's being shown in the code. The fact of using delete_prefix and/or delete_suffix doesn't mean you're going to delete the quotes surrounding strings. – Sebastián Palma Feb 05 '20 at 14:49
0

You're making it too difficult. I'd do this:

hg = "'Erra', 'Erra-Network', 'Discovery'"

hg.delete(" '").split(',') # => ["Erra", "Erra-Network", "Discovery"]

delete is doing the clean-up, which should be done before trying to split the string.

delete_prefix and delete_suffix are useful methods, but not when processing strings you're parsing because they force you into iteratively processing the sub-strings. delete does the entire string in one step, which is faster.

If I was going to iterate, I'd do something like this:

hg.split(/, */).map { |s| s[1..-2] } # => ["Erra", "Erra-Network", "Discovery"]

which takes advantage of split being able to take a regular expression to automatically break on a comma followed by any number of spaces. Basically you'll trying to parse a mangled CSV record, so you should use the CSV class. The documentation has many examples for parsing records:

require 'csv'
CSV.parse(hg.delete("' ")).flatten # => ["Erra", "Erra-Network", "Discovery"]

CSV has many options available for handling odd variations of delimiters and quoted strings, so study the documentation if you want to go that way.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
0

You could use CSV to get your result:

require 'csv'

string = "'Erra', 'Erra-Network', 'Discovery'"
result = CSV.parse_line(string, col_sep: ', ', quote_char: "'")
#=> ["Erra", "Erra-Network", "Discovery"]

Note that the above assumes that the separator is ', '. This means that a comma must always be followed by a space.

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52