The output of the [Character] Array currently is:
["E", "x", "a", "m", "p", "l", "e"]
It should be:
Example
It could be that " is in the array, like this: """. That output should be ".
Thank you!
The other answer(s) cover the case where your array is one of String elements (which is most likely the case here: since you haven't supplied us the type of the array, we could use Swift own type inference rules to speculatively infer the type to be [String]).
In case the elements of your array are in fact of type Character, however, you could use the Character sequence initializer of String directly:
let charArr: [Character] = ["E", "x", "a", "m", "p", "l", "e"]
let str = String(charArr) // Example
W.r.t. your comment below: if your example array is, for some reason, one of Any elements (which is generally not a good idea to use explicitly, but sometimes the case when recieving data from some external source), you first need to perform an attempted conversion of each Any element to String type, prior to concenating the converted elements to a single String instance. After the conversion, you will be working with an array of String elements, in which case the methods shown in the other answers will be the appropriate method of concenation:
// e.g. using joined()
let arr: [Any] = ["E", "x", "a", "m", "p", "l", "e"]
let str = arr.flatMap { $0 as? String }.joined()
print(str) // example
You could naturally also (attempt to) convert from Any to Character elements, but even in this case you would have to go via String instances, which means that for the [Any] case, the joined() alternative above is to prefer over the one below:
let arr: [Any] = ["E", "x", "a", "m", "p", "l", "e"]
let str = String(arr.flatMap { ($0 as? String)?.characters.first })
print(str) // example
Just use joined() with default "" separator:
let joinedString = ["E", "x", "a", "m", "p", "l", "e"].joined()
let e = ["E", "x", "a", "m", "p", "l", "e"]
print(e.reduce ("", +))
Related
Ruby 2.4. I have an array of strings
2.4.0 :007 > arr = ["a", "b", "g", "e", "f", "i"]
=> ["a", "b", "g", "e", "f", "h", "i"]
How do I split my array into smaller arrays based on a condition? I have a function -- "contains_vowel," which returns true if a string contains "a", "e", "i", "o", or "u". How would I take an array of strings and split it into smaller arrays, using a divider function of "contains_vowel"? That is, for the above, the resulting array of smaller arrays would be
[["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]
If an element of the larger array satisfies the condition, it would become an array of one element.
arr = ["a", "b", "g", "e", "f", "i"]
r = /[aeiou]/
arr.slice_when { |a,b| a.match?(r) ^ b.match?(r) }.to_a
=> [["a"], ["b", "g"], ["e"], ["f"], ["i"]]
String#match? made its debut in Ruby v2.4. For earlier versions you could use (for example) !!(b =~ r), where !! converts a truthy/falsy value to true/false. That converstion is needed because the XOR operator ^ serves double-duty: it's a logical XOR when a and b in a^b are true, false or nil, and a bit-wise XOR when the operands are integers, such as 2^6 #=> 4 (2.to_s(2) #=> "10"; 6.to_s(2) #=> "110"; 4.to_s(2) #=> "100").
One more way to skin a cat
def contains_vowel(v)
v.count("aeiou") > 0
end
def split_by_substring_with_vowels(arr)
arr.chunk_while do |before,after|
!contains_vowel(before) & !contains_vowel(after)
end.to_a
end
split_by_substring_with_vowels(arr)
#=> [["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]
What it does:
passes each consecutive 2 elements
splits when either of them contain vowels
Example with your other Array
arr = ["1)", "dwr", "lyn,", "18,", "bbe"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe"]]
Further example: (if you want vowel containing elements in succession to stay in the same group)
def split_by_substring_with_vowels(arr)
arr.chunk_while do |before,after|
v_before,v_after = contains_vowel(before),contains_vowel(after)
(!v_before & !v_after) ^ (v_before & v_after)
end.to_a
end
arr = ["1)", "dwr", "lyn,", "18,", "bbe", "re", "rr", "aa", "ee"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe", "re"], ["rr"], ["aa", "ee"]]
This checks if before and after are both not vowels Or if they both are vowels
I might use chunk which splits an array everytime the value of its block changes. Chunk returns a list of [block_value, [elements]] pairs, I used .map(&:last) to only get the sub-lists of elements.
arr = ["a", "b", "g", "e", "f", "h", "i"]
def vowel?(x); %w(a e i o u).include?(x); end
arr.chunk{|x| vowel?(x)}.map(&:last)
=> [["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]
contains_vowel = ->(str) { !(str.split('') & %w|a e i o u|).empty? }
_, result = ["a", "b", "g", "e", "f", "h", "i"].
each_with_object([false, []]) do |e, acc|
cv, acc[0] = acc[0], contains_vowel.(e)
cv ^ acc.first ? acc.last << [e] : (acc.last[-1] ||= []) << e
end
result
#⇒ [["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]
What we do here:
contains_vowel is a lambda to check whether the string contains a vowel or not.
we reduce the input array, collecting the last value (contained the previously handled string the vowel or not,) and the result.
cv ^ acc.first checks whether it was a flip-flop of vowel on the last step.
whether is was, we append a new array to the result
whether is was not, we append the string to the last array in the result.
This question already has answers here:
Removing duplicate elements from an array in Swift
(49 answers)
Swift 3 Generics: How to Find The Common Set of Two Generic Arrays
(2 answers)
Closed 6 years ago.
I have a formula retuning an array as example var Array = [a,s,d,s,f,g,g,h,e]. What I want is to run a for loop or some other option that gives me back a,s,d,f,g,h,e - only the unique values. How can I do this with ios Swift?
If you don't care about order:
Simply use a set:
let set: Set = ["a", "s", "d", "s", "f", "g" , "g", "h", "e"]
print(set) // ["a", "s", "f", "g", "e", "d", "h"]
If you care about the order:
Use this extension, which allows you to remove duplicate elements of any Sequence, while preserving order:
extension Sequence where Iterator.Element: Hashable {
func unique() -> [Iterator.Element] {
var alreadyAdded = Set<Iterator.Element>()
return self.filter { alreadyAdded.insert($0).inserted }
}
}
let array = ["a", "s", "d", "s", "f", "g" , "g", "h", "e"]
let result = array.unique()
print(result) // ["a", "s", "d", "f", "g", "h", "e"]
I need to render the contents of the first 5 elements of an array and display "And X more" on a web page. Is there a built-in method on Array (or Enumerable) that easily separates one array into two sub-arrays: the first consisting of up to a fixed size and the second consisting of the array remainder?
I'm looking for one simple method call that will do this for me. Most of the methods that I looked at (like Enumerable#partition) use a logical condition to divide the array and don't supply the index to the block.
I just wrote the following code to do what I want. Please save me from myself and direct me to a method that already does it.
class Array
def bifurcate(size=length)
if size < 0
raise ArgumentError, "attempt to bifurcate using negative size"
end
remainder_size = length - size
if remainder_size < 0
remainder_size = 0
end
[
first(size),
last(remainder_size)
]
end
end
('a'..'g').to_a.bifurcate(2)
# => [["a", "b"], ["c", "d", "e", "f", "g"]]
('a'..'g').to_a.bifurcate(20)
# => [["a", "b", "c", "d", "e", "f", "g"], []]
('a'..'g').to_a.bifurcate()
# => [["a", "b", "c", "d", "e", "f", "g"], []]
('a'..'g').to_a.bifurcate(0)
# [[], ["a", "b", "c", "d", "e", "f", "g"]]
('a'..'g').to_a.bifurcate(-1)
# ArgumentError: attempt to bifurcate using negative size
Also, let me qualify that I want one simple method call to do what I want. Also consider that the starting array may contain duplicate values and this method needs to respect the original array and return duplicates.
You can use Enumerable#partition along with Enumerator#with_index method, as shown below:
size = 2
(1..6).partition.with_index { |_,i| i < size }
#=> [[1, 2], [3, 4, 5, 6]]
Alternatively, if your input array can be mutated, then, following will also do the trick
[array.shift(size), array]
[array.take(3), array.drop(3)]
# [["a", "b", "c"], ["d", "e", "f", "g"]]
Hope it helps :)
Use Array#[]:
[arr[0,size_of_first], arr[size_of_first..-1] || []]
I'm trying to find a way to remove any elements in an array that fall between two "markers", but there are a few quirks. To give a proper spec, the function I'm making is supposed to do this:
Remove any elements from the earliest start marker S to the earliest end marker E after the S, or the final element if there is none. Repeat this until there are no Ss left. Remove any remaining Es.
For example, if I had an array containing the following:
This is my current code:
# if the starting token is `1` and the ending one is `2`:
while clearing.include? 1
from = clearing.index(1)
to = clearing[from..-1].index(2) + from
clearing.slice!(from..to)
end
clearing.delete(2)
Which, when run with clearing set to:
["a", "b", "c", "d", "e", "f", 1, "g", "h", "i", "j", 1, "k", 2, "l", 2, 2, "m", "n", "o", "p", "q", "r", "s", 1, "t", "u", "v", "w", "x", 1, "y", "z"]
properly returns
["a", "b", "c", "d", "e", "f", "l", "m", "n", "o", "p", "q", "r", "s"]
Online test
It works, but it's ugly, and I'm fairly sure there's a more idiomatic way to do it. I can't find it, though, or think of it, so I'm asking here: Is my code the only (sane) way to do what I'm trying to?
This is, unfortunately, a severe case of the XY problem -- the specific task I'm trying to accomplish is removing comments from a string. I could do this with a fairly simple regex (/#.*?$/m) if I had the input string, but because it's a class assignment, I have to delete from anything starting with # to the :newline token in an array of them. Please don't suggest "This is weird, why not try solving the overall problem a different way" -- I know it's weird. I wish I could.
Overall, I think any solution is going to be as elegant as yours. The only thing I can think of is that you could make it faster by iterating over each character only once:
i = 0
loop do
break if i >= clearing.length
break if clearing[i] == 1
i += 1
end
loop do
break if i >= clearing.length
val = clearing.delete(i)
break if val == 2
end
Which is definitely less elegant.
Ruby's fairly obscure "flip-flop" operator could be used here. I'm not recommending that it be used, just sayin'.
clearing.reject { |e| (e==1..e==2) ? true : false }.reject { |e| e==2 }
#=> ["a", "b", "c", "d", "e", "f", "l", "m", "n", "o", "p", "q", "r", "s"]
The first block returns false until 1 is detected. It then returns true for the 1 and continues to return true until 2 is detected. It returns true for the 2, but then returns false until the next (if any) 1 is detected, and so on. Hence, the name "flip-flop". The example often given for the flip-flop operator is reading sections of a file that are delimited with start/end markers.
It may seem that (e==1..e==2) ? true : false could be simplified to (e==1..e==2), but that is not the case, as the latter expression is treated as a normal range. Flip-flops must have a conditional form.
Replace both rejects with reject! if clearing is to be changed in place.
I am trying to compare a string variable to an element of a string array using a for loop in visual basic. I am comparing a user-entered string variable to an array with the lowercase alphabet, in order. I have some logical mistake because my "count" variable is always on 25 for some reason, and therefore it always says "Sorry, Try again" unless the user types a Z. Please help!
Dim lower() As String = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
For count As Integer = 0 To 25
input = txtInput.Text
input = input.ToLower
If input.Equals(lower(count)) Then
txtResult.Text = "Correct"
Else
txtResult.Text = "Sorry, Try again"
End If
Next
The problem is that you should exit the loop (with exit for) after you find a match. Otherwise, any mismatched characters will reset txtResults.Text to "Sorry, Try again." For example, when you enter "f", txtResults.Text is set to "Correct". But when you get to g, currently, it changes txtResults.Text to "Sorry, Try again.", and h, i, etc.
This is a good exercise in programming, but there is a shortcut you can use:
lower.contains(input.lower)
Info:
http://msdn.microsoft.com/en-us/library/dy85x1sa.aspx
Welcome to StackOverflow!
The reason you get "Correct" result only if you type "z" is that "z" is the last item of the array. If you type "y", the result will be correct for count = 24 (lower(24) = "y"), but at the next step it compares "y" with lower(25), which is actually "z". So txtResult.Text will be overwritten by "Sorry, Try again".
As I get your task correctly, you want to check if the input string is exists in the array. For that purpose you may use Array.Contains method:
Dim lower() As String = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
Dim input As String = txtInput.Text
If (lower.Contains(input)) Then
txtResult.Text = "Correct"
Else
txtResult.Text = "Sorry, Try again"
End If