s = "this is a test string"
words = {}
for w in s:gmatch("%w+") do table.insert(words, w) end
Using this code I was able to separate each word but now I need to be able to access just the nth word. How could I print just the second word for example? could I convert it to an array somehow then use something similar to
print words[2]
Like this:
s = "this is a test string"
words = {}
for w in s:gmatch("%w+") do
table.insert(words, w)
end
print (words [2]) --> is
for k, v in ipairs (words) do
print (v)
end -- for
Apart from printing "is" it follows it by:
is
a
test
string
print words[2]
You can only omit the parentheses for string literals and table constructors, like:
print "hello, world"
print ( table.getn { "the", "quick", "brown", "fox" } ) --> 4
Related
I'm working on a practice problem in Ruby. I already have the answer (below) but I'm not sure I understand how exactly one part of the answer works, specifically, how does new_word evaluate to a string if |word| is in an array. I may just be overlooking something super basic here but would appreciate any help. Thanks!
Prompt:
Write a method abbreviate_sentence that takes in a sentence string and returns a new sentence where every word longer than 4 characters has all of its vowels removed.
Answer:
words = sent.split(" ")
new_words = []
words.each do |word|
if word.length > 4
new_word = abbreviate_word(word)
new_words << new_word
else
new_words << word
end
end
return new_words.join(" ")
end
def abbreviate_word(word)
vowels = "aeiou"
new_word = ""
word.each_char do |char|
if !vowels.include?(char)
new_word += char
end
end
return new_word
end
puts abbreviate_sentence("follow the yellow brick road") # => "fllw the yllw brck road"
puts abbreviate_sentence("what a wonderful life") # => "what a wndrfl life" ```
Courtesy of #ggorlen:
You're iterating over an array of strings, so each |word| isn't an array, it's a string. This code could be sent.split(" ").map {|e| e.size > 4 ? e.gsub(/[aeiou]/, "") : e}.join(" ")
I have a beginner question. I'm trying to simply replace the modified index back in the original string to create an array of strings. They consecutively uppcase the next index in the following element.
Here's what I have. Can anyone help me see what I'm missing?
def wave(str)
result = []
index = 0
while index < str.length
i = str[index]
if i == " "
index =+ 1
else
upper = i.upcase
val = str.rindex(upper) -1
result.push("#{str[0...val]}#{str[val..-1]}")
index += 1
end
end
result
end
I'm trying to get:
["Hello", "hEllo", "heLlo", "helLo", "hellO"]
from ---> wave(hello)
Thank you.
Your else part isn't quite right:
you don't need to find the right-most index because you already have index
upper is never used
the right range is off by one
Here's a working variant:
# ...
else
upper = i.upcase
result.push("#{str[0...index]}#{upper}#{str[index+1..-1]}")
index += 1
end
# ...
You can use each_char and with_index to make your code a little more idiomatic:
def wave(str)
result = []
str.each_char.with_index do |char, index|
next if char == " "
result.push("#{str[0...index]}#{char.upcase}#{str[index+1..-1]}")
end
result
end
The problem is that you are declaring a variable upper but you are not using it.
Try to rewrite your code and this time use it.
If you are not sure what's happening in each line of code just put print in front of it.
Another option is to use Enumerable#map with Object#tap in this way:
str = 'hello'
str.size.times.map { |n| str.dup.tap { |s_dup| s_dup[n] = str[n].upcase } }
#=> ["Hello", "hEllo", "heLlo", "helLo", "hellO"]
Needs to duplicate the original string for avoiding change the original string itself which would return ["HELLO", "HELLO", "HELLO", "HELLO", "HELLO"]
For skipping spaces:
str.size.times.flat_map { |n| str.dup.tap { |s_dup| s_dup[n] = str[n].upcase } unless str[n] == ' ' }
I am trying to capitalize every even numbered placeholder in a string in Swift. So the character in [0],[2],[4],[6] all get uppercased.
I have a declared variable:
var str = "This is a test"
I have an array that explodes the variable into an array:
let characters = Array(str) //Creates the array "["T", "h", "i", "s", " ", "i", "s", " ", "a", " ", "t", "e", "s", "t"]\n"
On top of that, I am creating an empty array to input the newly capitalized/lowercased letters
var newCharacters = Array<Character>()
And then declaring index at 0
var index = 0 //declaring the index at 0
I am trying to figure out how to create the for loop that will sniff out the even numbered array item and then capitalize the character found in it.
I have created a for loop that will manipulate the even numbered placeholders in the array, I just do not know the syntax to capitalize the string of every other one:
for letter in characters {
if index % 2 == 0 {
}
}
I am trying to figure out: what the syntax is to capitalize every other letter (even numbers in the array), put them in the new array, and then convert it back to a string.
The end result should be:
"ThIs iS TeSt"
You can combine enumerated, map, and joined in sequence to create the result:
let str = "This is a test"
let result = str.enumerated()
.map { $0.offset % 2 == 0 ? String($0.element).uppercased() : String($0.element) }
.joined()
print(result)
ThIs iS A TeSt
Explanation:
A String can be enumerated as if it were an array of Character. Calling .enumerated() on a String causes it to produces a sequence of (offset: Int, element: Character) tuples.
map takes a sequence and creates an array. The closure following map is called for each element of the sequence in turn and the value that the closure returns becomes the next element in the new array.
$0 is the default name for the value passed to map. In this case, we're passing the (offset: Int, element: Character) tuple. $0.offset is the position of the character in the String, and $0.element is the character.
The ternary operator is used here to return the uppercased() String that is created from the Character if the offset is even or just the String if the offset is odd.
The result of the map is [String], and joined() is then used to join the array of String back into a single String.
One way is using stride:
var str = "This is a test"
var chars = Array(str).map { String($0) }
for i in stride(from: 0, to: chars.count, by: 2) {
chars[i] = chars[i].uppercased()
}
var hiphopcasedStr = chars.joined()
Note that while you're in Unicode land, some characters uppercase to multicharacter strings, so array of Character is not quite appropriate (thus the conversion to array of String).
let str = "This is a test"
let result = str.indices.map {
str.distance(from: str.startIndex, to: $0) % 2 == 0 ?
str[$0...$0].uppercased() :
str[$0...$0].lowercased() }.joined()
print(result) // "ThIs iS A TeSt\n"
or as a mutating method on StringProtocol:
extension StringProtocol where Self: RangeReplaceableCollection {
mutating func capitalizeEveryOther() {
indices.forEach {
replaceSubrange($0...$0, with:
distance(from: startIndex, to: $0) % 2 == 0 ?
self[$0...$0].uppercased() :
self[$0...$0].lowercased() )
}
}
var capitalizingEveryOther: Self {
var result = self
result.capitalizeEveryOther()
return result
}
}
var str5 = "This is a test"
str5.capitalizeEveryOther()
print(str5) // ThIs iS A TeSt
try this code
var str = "This is a test"
var result = [String]()
for (index,element) in str.enumerated() {
var val:String = String(element).lowercased()
if index % 2 == 0 {
val = String(element).uppercased()
}
result.append(val)
}
print(result.joined())
result
ThIs iS A TeSt
I am trying to take a sentence, and reverse the positions of the letters in each word.
Below is my code that does not work:
def test(sentence)
array = []
array << sentence.split
array.collect {|word| word.reverse}
end
My problem is with:
array << sentence.split
It says it divides each word, but when I use interpolation, it reverses the whole sentence. Below is a similar code that works:
def test2
dog = ["Scout", "kipper"]
dog.collect {|name| name.reverse}
end
But it does not accept a sentence, and it already has the array defined.
I'm thinking you want to split, then map each element of the array to its reversed version then rejoin the array into a string:
def test(sentence)
sentence.split.map {|word| word.reverse}.join(" ")
end
More concise using symbol-to-proc (credit #MarkThomas in comments)
sentence.split.map(&:reverse).join " "
Unlike methods that break up the sentence into words, reverses each word and then rejoins them, the use of Array#gsub with a regular expression preserves non-word characters (such as the comma in the example below) and multiple spaces.
"vieille, mère Hubbard".gsub(/\b\p{L}+\b/, &:reverse)
#=> "ellieiv, erèm drabbuH"
def reverse(str)
str.split.map { |s| s.length < 5 ? s : s.reverse }.join(' ')
end
puts reverse ("this is a catalogy")
This should reverse each word thats length upto 5
I try to find a library function in ML that equal to (cdr string) in Scheme (meaning (cdr abcd) = bcd).
(Asuming SML)
Another way is to convert the string to a list of chars (explode), then you have the option to take the head (hd) or tail (tl), and then finally convert it back to a string (implode):
- (implode o tl o explode) "this is a string";
val it = "his is a string" : string
The string conversion functions can be found in the String module, and the head and tail functions can be found in the List module
Obviously you can also use the substring method here, however in SML you have the extract function that are quite convenient in this case:
- String.extract("This is a string", 1, NONE);
val it = "his is a string" : string
Giving it the NONE argument makes it extract until the end of the string.
Assuming the Ocaml dialect, you could use the standard String module with e.g.
let rest_str str =
let slen = String.length str in
String.sub str 1 (slen-1)
;;