removing array brackets - arrays

I think its' silly question lol
I have below array
[['a','b','c'],['d','e','f']]
and want that array to be
['a','b','c'],['d','e','f']
which means i want to remove the first bracket.
Does that make sense?
Thanks in adv.

no, this doesn't make sense really, because ['a','b','c'],['d','e','f'] in this notation are two separate objects/arrays not inside any other data structure...
you could do an assignment, like :
a,b = [['a','b','c'],['d','e','f']]
and then
> a
=> ["a", "b", "c"]
> b
=> ["d", "e", "f"]
or better just iterate over the outer array (because you don't know how many elements it has):
input = [['a','b','c'],['d','e','f']]
input.each do |x|
puts "element #{x.inspect}"
end
=>
element ["a", "b", "c"]
element ["d", "e", "f"]

It doesn’t make sense. Do you mean a string manipulation?
irb(main):001:0> s = "[['a','b','c'],['d','e','f']]"
=> "[['a','b','c'],['d','e','f']]"
irb(main):002:0> s[1...-1]
=> "['a','b','c'],['d','e','f']"
Or, do you want to flatten an array?
irb(main):003:0> [['a','b','c'],['d','e','f']].flatten
=> ["a", "b", "c", "d", "e", "f"]

Related

How do I split an array into smaller arrays bsaed on a condition?

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.

How do I delete elements from an array at specified indexes, fi thsoe indexes are themselves in an array?

I'm using Ruby 2.4. If I have a group of array indexes, and I want to delete all the elements at those indexes, how do I do that? I tried the below, but its leaving stuff out
2.4.0 :005 > indexes_to_delete = [7, 8, 9]
=> [7, 8, 9]
2.4.0 :008 > a = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
2.4.0 :009 > indexes_to_delete.each do |index| a.delete_at(index) end
=> [7, 8, 9]
2.4.0 :010 > a
=> ["a", "b", "c", "d", "e", "f", "g", "i"]
Notice the ending array. I should have only seven elements in teh array since I started with ten and then specified three indexes of elements to delete in the array. Yet I have eight elements. How do I adjust my statement to delete the elements at the indexes I specified?
Every time you delete an item from an array the indexes change.
So you could do this:
3.times { a.delete_at(7) }
Which has the same effect of deleting at 7,8,9
Or use slice! as recommended here: How to delete a range of values from an array?
a.slice!(7..9)
to work with arbitrary arrays, i think the obvious choice would be reject with index:
a.reject.with_index { |item, idx| indexes_to_delete.include? idx }
This is non-mutating so you'd set a variable equal to the result.
Here are a couple of ways to do that.
indexes_to_delete = [3, 8, 9]
a = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
#1
indexes_to_delete.sort.reverse_each { |i| a.delete_at(i) }
a #=> ["a", "b", "c", "e", "f", "g", "h"]
This mutates a. If that's not desired, operate on a copy of a (a.dup).
Just remember that you must delete the elements in the reverse order of their indexes.
#2
a.values_at(*(0..a.size-1).to_a - indexes_to_delete)
#=> ["a", "b", "c", "e", "f", "g", "h"]
First we calculate the "keepers"
(0..a.size-1).to_a - indexes_to_delete
#=> [0, 1, 2, 4, 5, 6]
This does not mutate a. If a is to be mutated write
a.replace(a.values_at(*(0..a.size-1).to_a - indexes_to_delete))
#=> ["a", "b", "c", "e", "f", "g", "h"]
a #=> ["a", "b", "c", "e", "f", "g", "h"]
#maxple gives a third way (reject.with_index), which reads best to me. I doubt there are significant efficiency differences among the three.
Your problem is that the indexing changes when you do the delete. So don't delete at first.
a = ["a","b","c","d","e","f","g","h","i","j"]
to_delete = [7,8,9]
to_delete.each { |i| a[i] = nil }
a.compact!
Set the elements you want to delete to nil, and then compact the array to get rid of those elements.
If you have nil elements you want to keep, but you have a value that you know would never have in the array, you could do
MARK = special value
to_delete.each { |i| a[i] = MARK }
a.delete(MARK)

Is there a Ruby Array method that returns two sub-arrays: one of specified size and another of the remaining contents?

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] || []]

converting a string to an array and I keep getting an array with 1 object with the string crammed in that single index

I am new to ruby and trying to create a method that takes a string and returns an array with each letter as their own index in an array.
def validate_word(word)
w=[]
word.downcase!
w << word.split(//)
return w
end
validate_word("abcABC")
=> [["a", "b", "c", "a", "b", "c"]]
I would like it to return
=>["a", "b", "c", "a", "b", "c"]
Thank you for looking at my code.
In your code you do not need to create a new array, since String#split returns array which you want. Also, Ruby returns last string of a method by default, so you can write:
def validate_word(word)
word.downcase!
word.split(//) # or you can chain methods: word.downcase.split('')
end
validate_word("abcABC")
=> ["a", "b", "c", "a", "b", "c"]
Note: do not use methods with exclamation mark (downcase!) except cases when you want modify source object. Use alternative methods(downcase) instead.

Ruby. How to split a string element inside an array?

I have an array of arr=["abcd"]
Q1. Is there a simpler way to split the 'abcd' into arr=["a","b","c","d"] than the following:
arr=["abcd"]
arr_mod=[]
x=0
while x < arr[0].size
arr_mod << arr[0][x]
x +=1
end
puts "==>#{arr_mod}"
arr.split('') will not work.
Q2. Is there a method to convert arr=["abcd"] to the string of "abcd"?
arr.first.split('')
#=> ["a", "b", "c", "d"]
arr.first
#=> "abcd"
Q1:
This would give you some flexibility in case you ever needed a way to iterate over an array of more than one element:
arr = ['abcd']
arr = arr[0].split("")
#=> ["a", "b", "c", "d"]
Q2:
arr = ['abcd']
arr = arr[0]
#=> "abcd"
Simplest way is to do
arr.join("").chars
This turns the arr into one big string, then turns that string into an array of characters.
For your second question, just do arr.join(""), which will turn all the strings into the array into one big string.
For more information, check out Array#join and String#chars for more detail.
Q1:
arr.map(&:chars).flatten
#=> ["a", "b", "c", "d"]
Q2:
arr = arr[0]
#=> "abcd"
This is one way:
arr.join.split('') #=> ["a", "b", "c", "d"]

Resources