I am trying to split a string, and output the different parts, whats the best practice for rails 3 ?
String: "book_page_title"
Seperator: "_"
I want to have book, page and title as seperate variables, so that
I can perform actions on them..
Any help is appreciated.
Also, I am having trouble finding good reference sites, with examples like PHP have, and suggestions ?
To split:
book,page,title = string.split('_')
And to recombine:
string = [book,page,title].join('_')
use
split('_')
method it gives array.
Try ruby+string+doc in google, you will get http://ruby-doc.org/core/classes/String.html as the first result, and you can see a number of string functions in this link. You can see split there.
splitted_array = "book_page_title".split("_")
=> ["book", "page", "title"]
splitted_array.each do |string|
#..do manipulations here
end
"book_page_title".split("_") will return you array of strings. So you can access every element via [].
splitted = "book_page_title".split("_") # ["book", "page", "title"]
puts splitted[0] # gives "book"
puts splitted[1] # gives "page"
puts splitted[2] # gives "title"
a = "book_page_title".split("_")
a.each do |i|
instance_variable_set("##{i}", "value")
end
#book #=> *value*
#page #=> *value*
#title #=> *value*
Related
I need to Separate multiple Array entries with a newline.
the names in the aray value. Again I want to split the array like seperate names.
Eg. names="alice\nbob"
and I want names=alice&names=bob. How can I get that??
Try this:
names="alice\nbob"
names = names.split("\n").map{|item| "names=#{item}"}.join("&")
#=> "names=alice&names=bob"
If intention is to have it in form of query parameters, I will suggest using Addressable::URI:
require "addressable/uri"
def return_query(str)
uri = Addressable::URI.new
uri.query_values = {:names => str.split("\n") }
uri.query
end
return_query("alice\nbob") #=> "names=alice&names=bob"
return_query("alice in wonderland\nbob") #=> "names=alice%20in%20wonderland&names=bob"
return_query("alice&wonderland\nbob") #=> "names=alice%26wonderland&names=bob"
Is it possible to set a conditional statement (IF statement) comparing a variable against a variable that iterates through the values inside an array? I was looking for something like:
array_of_small_words = ["and","or","be","the","of","to","in"]
if word == array_of_small_words.each
# do thing
else
# do another thing
end
Basically, I want to capitalize each word but don't want to do it for "small words". I know I could do the the opposite and iterate through the array first and then compare each iteration with the word but I was hoping there would be a more efficient way.
sentence = ["this","is","a","sample","of","a","title"]
array_of_small_words = ["and","or","be","the","of","to","in"]
sentence.each do |word|
array_of_small_words.each do |small_words|
if word == small_words
# don't capitalize word
else
# capitalize word
end
end
end
I'm not really sure if this is possible or if there is a better way of doing this?
Thank you!
sentence = ["this","is","a","sample","of","a","title"]
array_of_small_words = ["and","or","be","the","of","to","in"]
sentence.map do |word|
array_of_small_words.include?(word) ? word : word.upcase
end
#⇒ ["THIS", "IS", "A", "SAMPLE", "of", "A", "TITLE"]
What you're looking for is if array_of_small_words.include?(word).
This should be faster than #mudasobwa's repeated use of include? if packaged in a method and used frequency. It would not be faster, however, if mudsie used a set lookup (a minor change, of which he is well-aware), as I mentioned in a comment. If efficiency is important, I'd prefer mudsie's way with the set mod over my answer. In a way I was just playing around below.
I've assumed he small words are and, or, be, the, of, to, in and notwithstanding.
SMALL_WORDS = %w| and or be the of to in notwithstanding |
#=> ["and", "or", "be", "the", "of", "to", "in", "notwithstanding"]
(SMALL_WORDS_HASH = SMALL_WORDS.map { |w| [w.upcase, w] }.to_h).
default_proc = proc { |h,k| h[k]=k }
Test:
SMALL_WORDS_HASH
#=> {"AND"=>"and", "OR"=>"or", "BE"=>"be", "THE"=>"the", "OF"=>"of",
# "TO"=>"to", "IN"=>"in", "NOTWITHSTANDING"=>"notwithstanding"}
SMALL_WORDS_HASH["TO"]
#=> "of"
SMALL_WORDS_HASH["HIPPO"]
#=> "HIPPO"
def convert(arr)
arr.join(' ').upcase.gsub(/\w+/, SMALL_WORDS_HASH)
end
convert ["this","is","a","sample","of","a","title"]
#=> "THIS IS A SAMPLE of A TITLE"
So i have a json here and im trying to search for name
I am trying to read through the whole json, and only match to name. But im not sure how to go about that.
I parsed the json below into a variable called jsondata
and created this loop here to read it.
jsondata.each do |links|
puts links
end
But how can i go about only reading the name field and matching it to a string? Lets say im looking looking for the word leo.
{"files":[{"name":"github.jpeg","size":10852,"deleteType":"DELETE","deleteUrl":"http://gifs.meow.me/github.jpeg","url":"http://gifs.meow.me/github.jpeg"},{"name":"leo.jpg","size":51678,"deleteType":"DELETE","deleteUrl":"http://gifs.meow.me/leo.jpg","url":"http://gifs.meow.me/leo.jpg"},{"name":"leo2.jpg","size":41407,"deleteType":"DELETE","deleteUrl":"http://gifs.meow.me/leo2.jpg","url":"http://gifs.meow.me/leo2.jpg"}]}
You can search each string under the key of "name" for the needle you're looking for using String#include? or String#index. The Enumerable method select would be a good choice for selecting only the hashes that contain the data you're looking for:
jsondata["files"].select{|h| h["name"].include? "leo" }
This presumes you have parsed the json data into a Ruby hash:
jsondata = {"files"=>[
{"name"=>"github.jpeg",
"size"=>10852,
"deleteType"=>"DELETE",
"deleteUrl"=>"http=>//gifs.meow.me/github.jpeg",
"url"=>"http=>//gifs.meow.me/github.jpeg"},
{"name"=>"leo.jpg",
"size"=>51678,
"deleteType"=>"DELETE",
"deleteUrl"=>"http=>//gifs.meow.me/leo.jpg",
"url"=>"http=>//gifs.meow.me/leo.jpg"},
{"name"=>"leo2.jpg",
"size"=>41407,
"deleteType"=>"DELETE",
"deleteUrl"=>"http=>//gifs.meow.me/leo2.jpg",
"url"=>"http=>//gifs.meow.me/leo2.jpg"}
]}
jsondata["files"].select{|h| h["name"].include? "leo" }
# => [{"name"=>"leo.jpg", "size"=>51678, "deleteType"=>"DELETE", "deleteUrl"=>"http=>//gifs.meow.me/leo.jpg", "url"=>"http=>//gifs.meow.me/leo.jpg"}, {"name"=>"leo2.jpg", "size"=>41407, "deleteType"=>"DELETE", "deleteUrl"=>"http=>//gifs.meow.me/leo2.jpg", "url"=>"http=>//gifs.meow.me/leo2.jpg"}]
jsondata.each do |link|
if link.name =~ /leo/
# do something
end
end
or
jsondata.each do |link|
if link.name.include? 'leo'
# do something
end
end
Using jsondata as defined by #Cam, you can do the following.
jsondata["files"].each_with_object({}) { |g,h|
h[g["name"]]=g["url"] if g["name"] =~ /\Aleo/ }
#=> {"leo.jpg"=>"http=>//gifs.meow.me/leo.jpg",
# "leo2.jpg"=>"http=>//gifs.meow.me/leo2.jpg"}
I have a hash whose value is an array of song lyrics (line1, line2, etc..)
Code:
class Song
def initialize(lyrics)
#lyrics = lyrics
end
def get_song_name()
puts #lyrics.keys
end
def get_first_line()
puts #lyrics.values[0]
end
end
wasted = Song.new({"Wasted" => ["I like us better when we're wasted",
"It makes it easier to see"]})
real_world = Song.new("Real World" => ["Straight up what do you want to learn about here", "if i was someone else would this all fall apart"])
wasted.get_song_name()
wasted.get_first_line()
#=>I like us better when we're wasted
#=>It makes it easuer to see
So when I called wasted.get_first_line, I want it to get the first item in the array of the value. I tried doing #lyrics.values[0], but it returns both lines of the song instead of the first one.
How do I accomplish this?
You need to understand that in the above code #lyrics is a Hash. Here is what you are doing and what it translates to:
#lyrics
# => {"Wasted"=>["I like us better when we're wasted", "It makes it easier to see"]}
#lyrics.values
# => [["I like us better when we're wasted", "It makes it easier to see"]]
#lyrics.values[0]
# => ["I like us better when we're wasted", "It makes it easier to see"]
#lyrics.values[0][0]
# => "I like us better when we're wasted"
Therefore to access the first line, you need to get the first element of the values array. i.e.
#lyrics.values[0][0]
or
#lyrics.values.first.first
Lets use this hash for example:
x = {foo: [:bar, :baz]}
x.values # => [[:bar, :baz]]
x.values.first # => [:bar, :baz]
x.values.first.first # => :bar
In other words, #lyrics.values[0] will return the first value in the #lyrics hash, which is the array of two songs. You still have to get the first song out of that array.
This is not the answer to original question, but if I were you, I would modify the class like below. It will be more apt to store song name and lines of lyrics as individual attributes, instead of merging them as a hash - which kind of defies the whole purpose of having Song class.
class Song
attr_accessor :song_name, :lyrics
def initialize(song_name, lyrics)
#song_name = song_name
#lyrics = lyrics
end
end
Please note that you may not need get_first_line method. You could always use Array#first to have same effect:
real_world = Song.new("Real World", ["Line 1", "Line 2"])
puts real_world.lyrics.first # Prints "Line 1"
You can also access lyrics lines using array index
puts real_world.lyrics[1] # Prints "Line 2"
I have the following in my url. I need to extract both 4 and 2 separately for the purpose of searching. These two integer, one is category id and other is sub category id
params[:id].scan(/\d+$/).first
using the above scan i can get 4 but how can i get more than one integers
my-url-for-test-4-2
I have created a helper method
def string_to_int(param,key)
param.scan(/\d+/).map(&:to_i).key
end
And i tried it from my controller like this
id = string_to_int(params[:id],'first')
But getting error as
undefined method `key' for [4, 2]:Array
Why it is not acception.
Answer lies in your question
params[:id].scan(/\d/) will result in array.
params[:id].scan(/\d+/).map(&:to_i)
If you are passing first or last as key :
def string_to_int(param,key)
param[:id].scan(/\d+/).map(&:to_i).send(key)
end
You can match against the last two numerical parts (separated by hyphens) in your :id parameter:
string = params[:id].to_s
ids = string.scan(/-(\d+)-(\d+)$/)[0] # .try(:map, &:to_i)
Update:
Here's a not-too-edge case that would be handled well:
a = "random1-2string-3-4-5"
a.scan(/-(\d+)-(\d+)$/) # => [["4", "5"]]
a.scan(/-(\d+)-(\d+)$/)[0] # => ["4", "5"]
a.scan(/-(\d+)-(\d+)$/)[0].try(:map, &:to_i) # => [4, 5]