I have this string: This is my example #foo and #bar
And this array: ['#foo','#bar']
And this is the string I would like to have: This is my example and
Thx!
Define your string and array:
s = "This is my example #foo and #bar"
a = ['#foo', '#bar']
Then:
answer_array = (s.split(" ") - a).join(" ")
Gives the answer:
=> "This is my example and"
The following preserves whitespace:
str = 'This is my example #foo and #bar'
arr = ['#foo','#bar']
r = Regexp.new arr.each_with_object('') { |s,str| str << s << '|' }[0..-2]
#=> /#foo|#bar/
str.gsub(r,'')
#=> "This is my example and "
Another example (column labels):
str = " Name Age Ht Wt"
arr = [' Age', ' Wt']
r = Regexp.new arr.each_with_object('') { |s,str| str << s << '|' }[0..-2]
#=> / Age| Wt/
str.gsub(r,'')
#=> " Name Ht"
Related
Problem:
I have a given string = "Hello #User Name and hello again #Full Name and this works"
Desired output: = ["#User Name, #Full Name"]
Code I have in Swift:
let commentString = "Hello #User Name and hello again #Full Name and this works"
let words = commentString.components(separatedBy: " ")
let mentionQuery = "#"
for word in words.filter({ $0.hasPrefix(mentionQuery) }) {
print(word) = prints out each single name word "#User" and "#Full"
}
Trying this:
if words.filter({ $0.hasPrefix(mentionQuery) }).isNotEmpty {
print(words) ["Hello", "#User", "Name".. etc.]
}
I'm stuck on how to get an array of strings with the full name = ["#User Name", "#Full Name"]
Would you know how?
First of all, .filter means that check each value in the array which condition you given and if true then take value - which not fit here.
For the problem, it can divide into two task: Separate string into substring by " " ( which you have done); and combine 2 substring which starts with prefix "#"
Code will be like this
let commentString = "Hello #User Name and hello again #Full Name"
let words = commentString.components(separatedBy: " ")
let mentionQuery = "#"
var result : [String] = []
var i = 0
while i < words.count {
if words[i].hasPrefix(mentionQuery) {
result.append(words[i] + " " + words[i + 1])
i += 2
continue
}
i += 1
}
The result
print("result: ", result) // ["#User Name", "#Full Name"]
You can also use filter, like this below:
let str = "Hello #User Name and hello again #Full Name"
let res = str.components(separatedBy: " ").filter({$0.hasPrefix("#")})
print(res)
// ["#User", "#Full"]
I am trying to define a function in scala ( ^ ), which takes 2 values and prints them like
2
x
Here is what I have so far...
class $ (val text2D: Array[Array[Char]])
{
def ^(that: $) =
{
" " ++ s"${this.text2D(0)(0)}" ++
"\n" ++ s"${that.text2D(0)(0)}"
}
def +(that: $) = this.text2D + "+" + that.text2D
override def toString = s"${this.text2D(0)(0)}"
}
object $ {
val array = Array.ofDim[Char](1,1)
def apply(x: String): $ = {
array (0)(0) = x.charAt(0)
new $ (array)
}
}
val x = $("x")
println(x)
val x2 = $("x") ^ $("2")
println(x2)
When I run this, I do not get the output I am expecting, instead I get
2
2
Why is it only taking the second element? Any help would be appreciated.
object creates a singleton, so the (mutable) array that you use is shared between calls to apply. You need to allocate that array inside the apply call.
def apply(x: String): $ = {
val array = Array.ofDim[Char](1,1)
array (0)(0) = x.charAt(0)
new $ (array)
}
Also, slightly unrelated, but I believe you have your arguments backward. To get the output you want, you need
" " ++ s"${that.text2D(0)(0)}" ++
"\n" ++ s"${this.text2D(0)(0)}"
I think what you need is something like this:
class $(val text2D: Array[String]) {
def ^(that: $): $ = {
if (this.text2D.length == 0)
that
else if (that.text2D.length == 0)
this
else {
val thisW = this.text2D(0).length
val thatW = that.text2D(0).length
// cross-pad arrays to have the same width
val padThisRight = " " * thatW
val padThatLeft = " " * thisW
val thisPaddedW = this.text2D.map(_ + padThisRight)
val thatPaddedW = that.text2D.map(padThatLeft + _)
// first lines comes from that!
new $(thatPaddedW ++ thisPaddedW)
}
}
def +(that: $): $ = {
if (this.text2D.length == 0)
that
else if (that.text2D.length == 0)
this
else {
val thisH = this.text2D.length
val thatH = that.text2D.length
val thisW = this.text2D(0).length
val thatW = that.text2D(0).length
// pad arrays to have the same height
val emptyThis = " " * thisW
val emptyThat = " " * thatW
val thisPaddedH = if (thisH >= thatH) this.text2D else Array.fill(thatH - thisH)(emptyThis) ++ this.text2D
val thatPaddedH = if (thisH <= thatH) that.text2D else Array.fill(thisH - thatH)(emptyThat) ++ that.text2D
new $(thisPaddedH.zip(thatPaddedH).map(p => p._1 + p._2))
}
}
override def toString = text2D.mkString("\n")
}
object $ {
def apply(x: String): $ = {
new $(Array[String](x))
}
}
and then
val x2 = $("x") ^ $("2")
println(s"x2:\n$x2")
println("----------------------------")
val z = x2 + $(" + ") + y2
println(s"z:\n$z")
println("----------------------------")
val zz = x2 + $(" + ") + (y2 ^ $("3"))
println(s"zz:\n$zz")
println("----------------------------")
produces following output
x2:
2
x
----------------------------
z:
2 2
x + y
----------------------------
zz:
3
2 2
x + y
----------------------------
The main idea here is that operations on $ produce another instance of $ rather than String (I use String instead of Array[Char] as it seems much easier and has no obvious drawbacks). In such way you don't have to re-parse String splitting it by new lines and have to wonder how to handle cases when the string is not well-aligned. So now operators ^ and + is just an exercise in aligning two 2d-arrays to have either the same width or the same height and then joining them.
How to remove the first word of a string?
0.91% ABC DEF
0.922% ABC DEF GHI
OUTPUT: ABC DEF / ABC DEF GHI
I tried
let test = str.split(separator: " ")[1...]
print(test)
print(test.joined(separator: " "))
Which gives me:
["ABC", "DEF"]
JoinedSequence<ArraySlice<Substring>>(_base: ArraySlice(["ABC", "DEF"]), _separator: ContiguousArray([" "]))
How can I print the JoinedSequence as a string?
Try this:
let str = "0.91% ABC DEF"
var parts = str.components(separatedBy: " ").dropFirst()
print(parts.joined(separator: " "))
Which prints:
"ABC DEF\n"
Given a string
let text = "0.91% ABC DEF"
you can search for the ´index´ after the first space
if let index = text.range(of: " ")?.upperBound {
let result = text.substring(from: index)
print(result)
}
I want to convert an array in to a string with two different separators at two different places. meaning:
array = [1,2,3,4]
after converting: separator 1: (":") separator 2: ("and")
string = "1:2:3: and 4"
OR
string = "1:2 and 3:4"
How can I build dynamic and short code that lets me convert an array (of any length) into a string which allows me to insert more than one separator and at different positions.
My current solution is messy and hideous:
I have used #join with a single argument.
def oxford_comma(array)
if array.length == 1
result_at_1 = array.join
return result_at_1
elsif array.length == 2
result_at_2 = array.join(" and ")
return result_at_2
elsif array.length == 3
last = array.pop
result = array.join(", ")
last = ", and " + last
result = result + last
elsif array.length > 3
last = array.pop
result = array.join(", ")
last = ", and " + last
result = result + last
return result
end
end
Can someone please help me establish a better, shorter and more abstract method of doing this?
You can use Enumerable#slice_after.
array.slice_after(1).map { |e| e.join ":" }.join(" and ") #=> "1 and 2:3:4"
array.slice_after(2).map { |e| e.join ":" }.join(" and ") #=> "1:2 and 3:4"
array.slice_after(3).map { |e| e.join ":" }.join(" and ") #=> "1:2:3 and 4"
If you're using rails/activesupport, then it's built-in:
[1,2,3,4].to_sentence # => "1, 2, 3, and 4"
[1,2].to_sentence # => "1 and 2"
[1,2,3,4].to_sentence(last_word_connector: ' and also ') # => "1, 2, 3 and also 4"
If you don't, go copy the activesupport's implementation, for example :)
Note: this does not allow you to place your "and" in the middle of the sequence. Perfect for oxford commas, though.
pos = 2
[array[0...pos], array[pos..-1]].
map { |e| e.join ':' }.
join(' and ')
#⇒ "1:2 and 3:4"
Code
def convert(arr, special_separators, default_separator, anchors={ :start=>'', :end=>'' })
seps = (0..arr.size-2).map { |i| special_separators[i] || default_separator }
[anchors.fetch(:start, ""), *[arr.first, *seps.zip(arr.drop(1)).map(&:join)],
anchors.fetch(:end, "")].join
end
Examples
arr = [1,2,3,4,5,6,7,8]
default_separator = ':'
#1
special_separators = { 1=>" and ", 3=>" or " }
convert(arr, special_separators, default_separator)
#=> "1:2 and 3:4 or 5:6:7:8"
where
seps #=> [":", " and ", ":", " or ", ":", ":", ":"]
#2
special_separators = { 1=>" and ", 3=>") or (", 5=>" and " }
convert(arr, special_separators, default_separator, { start: "(", end: ")" })
#=> "(1:2 and 3:4) or (5:6 and 7:8)"
where
seps #=> [":", " and ", ":", ") or (", ":", " and ", ":"]
i need help, about how to replace my array2d with another array1d
example array2d, that i have
role = {{"mike", "30", "1"},
{"mike", "50", "3"}}
i want to replace the third array value "role[...][3]" with this array1d
role_listname = {
[1] = "Winner!",
[2] = "Funnier!",
[3] = "Crazy!"
}
so the result i got.
1. Winner - 30p
2. Crazy - 50p
Not like
1. Winner - 30p
2. Funnier - 40p
my code :
for i = 1, #role do
role[i][3] = role_listname[i]
print(i .. ". " .. role[i][3] .. " - " .. role[i][2])
end
i don't know. it's not working, could you tell me how it's work ?
You logic is wrong. You are using the loop variable i as index, but you want to use the corresponding entry in the role table:
role = {
{"mike", "30", 1},
{"mike", "50", 3}
}
role_listname = {
[1] = "Winner!",
[2] = "Funnier!",
[3] = "Crazy!"
}
for i = 1, #role do
role[i][3] = role_listname[role[i][3]] -- here is the change
print(i .. ". " .. role[i][3] .. " - " .. role[i][2])
end
Note that i also switched the indices in the role table to numerics. But this does not really matter, you could use any keys. They just have to match with the corresponding keys in the role_listname table.