How do I go about removing the tabs, new lines, and whitespaces from this array?
array1 = ["E", "A", "C", "H", " ", "L", "I", "N", "E", " ", "E", "N", "D", "S", " ", "W", "I", "T", "H", " ", "A", " ", "A", "C", "C", "I", "D", "E", "N", "T", "A", "L", "L", "Y", " ", " ", "A", "D", "\"", "A", " ", "A", "C", "C", "I", "\n", "\""]
I have tried the following, and none of these seem to work properly.
array1.map!(&:strip)
array1.reject!(&:empty?)
array1.reject(&:empty?)
array1 - [""]
array1.delete_if {|x| x == " " }
array1 = ["E", " ", ":", "L", "É", "\t", "T",
"-", "H", "\n", "\""]
array1.reject { |s| s.match? /\s/ }
#=> ["E", ":", "L", "É", "T", "-", "H", "\""]
\s in a regular expression matches all whitespace characters, namely, spaces, tabs ("\t") newlines ("\n"), carriage returns ("\r") and formfeeds ("\f").
The latter two have their origins from the days when teletype machines were used, the carriage return being the movement of the printhead from the end to the beginning of the line and the formfeeds advancing the paper being printed one line.1
1 Microsoft Windows still recognizes carriage returns and formfeeds, thereby maintaining support for teletype machines. ¯\_(ツ)_/¯
You can use grep to select elements matching a pattern. That pattern can be a simple regexp like /\s/ which matches whitespace characters:
array1.grep(/\s/)
#=> [" ", " ", " ", " ", " ", " ", " ", " ", "\n"]
The result is an array with all elements containing at least one whitespace character.
There's also \S (uppercase) which matches non-whitespace characters:
array1.grep(/\S/)
#=> ["E", "A", "C", "H", "L", "I", "N", "E", "E", "N", "D", "S", "W",
# "I", "T", "H", "A", "A", "C", "C", "I", "D", "E", "N", "T", "A",
# "L", "L", "Y", "A", "D", "\"", "A", "A", "C", "C", "I", "\""]
And we have grep_v which is the inverted version of grep. This would be useful if you wanted to specify space, tab and newline explicitly:
array1.grep_v(/[ \t\n]/)
#=> ["E", "A", "C", "H", "L", "I", "N", "E", "E", "N", "D", "S", "W",
# "I", "T", "H", "A", "A", "C", "C", "I", "D", "E", "N", "T", "A",
# "L", "L", "Y", "A", "D", "\"", "A", "A", "C", "C", "I", "\""]
In addition, just other possible variants:
array1 = [" ", "A", "\n", "\t", "B", "\r"]
array1.delete_if { |s| s.match? /\s/ }
#=> ["A", "B"]
array1 = [" ", "A", "\n", "\t", "B", "\r"]
array1.keep_if { |s| !s.match? /\s/ }
#=> ["A", "B"]
array1 = [" ", "A", "\n", "\t", "B", "\r"]
array1.select! { |s| !s.match? /\s/ }
#=> ["A", "B"]
Using match? rather than match is more preferable not only because we don’t use MatchData.
The point is that the benchmark shows that match? is almost 2 times faster.
This can be significant when working with large amounts of data.
Related
local function generator()
local capital_letters = {"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"}
local low_letters = {"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"}
local numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
local Random_capital_letters = math.random(26)
local Random_low_letters = math.random(26)
local Random_numbers = math.random(10)
local length = 10
print("this is your generatet password: "..Random_capital_letters, Random_low_letters, Random_numbers[length])
math.randomseed(os.time())
end
generator()
it just gives me an error all the time, would be cool if anyone could help me!
You must initialize random seed before using math.random
It's better to use length of your tables (capital_letters, low_letters, numbers) to use math.random function to pick a value and create your password.
10 value must not be in numbers table
A loop is necessary to create your password : iterate from 1 to length and in each step, pick a random value in capital_letters, low_letters, numbers tables.
A working version adapted from your Lua code :
local function generator()
local capital_letters = {"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"}
local low_letters = {"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"}
local numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
math.randomseed(os.time())
local length = 10
local pass = ""
local choice = 0
for _ = 1, length do
choice = math.random(3)
-- Capital letters
if choice == 1 then
pass = pass .. capital_letters[math.random(#capital_letters)]
-- Low letters
elseif choice == 2 then
pass = pass .. low_letters[math.random(#low_letters)]
-- Numbers
else
pass = pass .. numbers[math.random(#numbers)]
end
end
print(pass)
end
generator()
When I run this code I get a typeError, but when I do it by hand in the IRB everything seems to be working out okay. I believe the problem lies somewhere in my IF statement but I don't know how to fix it.
numerals = ["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"]
def convertToNumbers(string)
arr = string.downcase.split('')
new_array = []
arr.each do |i|
if (arr[i] =~ [a-z])
numValue = numerals.index(arr[i]).to_s
new_array.push(numValue)
end
end
end
You probably meant
arr[i] =~ /[a-z]/
which matches the characters a through z. What you wrote
arr[i] =~ [a-z]
is constructing an array and trying to compare it using the regex comparison operator, which is a type error (assuming variables a and z are defined).
A few issues. As Tyler pointed out inside of the loop you are still referencing arr when you look to only need to use i. Also, the regex issue Max pointed out is valid as well. The function also will return arr and not the new_array array as that is the result of the for loop output.
I made a few modifications.
def convertToNumbers(string)
numerals = ["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"]
arr = string.downcase.split('')
new_array = []
arr.each do |i|
if (i =~ /[a-z]/)
numValue = numerals.index(i).to_s
new_array.push(numValue)
end
end
new_array.join
end
puts convertToNumbers('abcd');
which prints out '0123'
a=b&c=d&e=f&g=h
How to extract this into [a,b,c,d,e,f,g,h]
I know I can use split, but it looks like it can only use only one delimit.
or how to convert into a hash?
split FTW (i.e. the most straightforward, simple way of doing this is):
irb(main):001:0> s = "a=b&c=d&e=f&g=h"
=> "a=b&c=d&e=f&g=h"
irb(main):002:0> s.split(/[=&]/)
=> ["a", "b", "c", "d", "e", "f", "g", "h"]
Other interesting ways of abusing Ruby:
irb(main):001:0> s = "a=b&c=d&e=f&g=h"
=> "a=b&c=d&e=f&g=h"
irb(main):002:0> s.split('=').collect{|x| x.split('&')}.flatten
=> ["a", "b", "c", "d", "e", "f", "g", "h"]
irb(main):003:0> ['=','&'].inject(s) {|t, n| t.split(n).join()}.split('')
=> ["a", "b", "c", "d", "e", "f", "g", "h"]
Also check Cary's and GamesBrainiac's answers for more alternatives :)
You can make a hash very easily with something like this:
myHash = {}
strSplit = "a=b&c=d&e=f&g=h".split("&")
for pair in strSplit
keyValueSplit = pair.split("=")
myHash[keyValueSplit[0]] = keyValueSplit[1]
end
myHash will look like this in the end {"a"=>"b", "c"=>"d", "e"=>"f", "g"=>"h"}
#Mirea's answer is best, but here's another:
s = "a=b&c=d&e=f&g=h"
s.scan /[a-z]/
#=> ["a", "b", "c", "d", "e", "f", "g", "h"]
The regex could of course be adjusted as required. For example:
"123a=b&c=d&E=f&g=h".scan /[A-Za-z0-9]/
#=> ["1", "2", "3", "a", "b", "c", "d", "E", "f", "g", "h"]
or
"1-2-3a=$b&c=d&e=f&g=h".scan /[^=&]/
#=> ["1", "-", "2", "-", "3", "a", "$", "b", "c", "d", "e", "f", "g", "h"]
and so on.
If strings of characters are desired just append + to the character class:
"123a=b&ccc=d&E=f&gg=h".scan /[A-Za-z0-9]+/
#=> ["123a", "b", "ccc", "d", "E", "f", "gg", "h"]
If the string has the alternating form shown in the example, these work as well:
(0..s.size).step(2).map { |i| s[i] }
#=> ["a", "b", "c", "d", "e", "f", "g", "h"]
s.each_char.each_slice(2).map(&:first)
#=> ["a", "b", "c", "d", "e", "f", "g", "h"]
I would use is gsub.
irb(main):001:0> s = "a=b&c=d&e=f&g=h"
=> "a=b&c=d&e=f&g=h"
irb(main):004:0> s.gsub(/[\=\&]/, " ").split()
=> ["a", "b", "c", "d", "e", "f", "g", "h"]
So, what we're doing here is replacing all occurrences of = and & with a single space. We then simply split the string.
Let's say I have nested array like:
nested = [
[0.5623507523876472, ["h", "e", "l", "l", "o"]],
[0.07381531933500263, ["h", "a", "l", "l", "o"]],
[0.49993338806153054, ["n", "i", "h", "a", "o"]],
[0.6499234734532127, ["k", "o", "n", "n", "i", "c", "h", "i", "w", "a"]]
]
Initially I wanted to convert it into hash. But first I have to convert array(above example ["h", "e", "l", "l", "o"]) to "hello".
So my question is how to convert nested into :
[
[0.5623507523876472, "hello"],
[0.07381531933500263, "hallo"],
[0.49993338806153054, "nihao"],
[0.6499234734532127, "konnichiwa"]
]
If you don't want to destroy the source array nested :
Use Array#map :
nested = [
[0.5623507523876472, ["h", "e", "l", "l", "o"]],
[0.07381531933500263, ["h", "a", "l", "l", "o"]],
[0.49993338806153054, ["n", "i", "h", "a", "o"]],
[0.6499234734532127, ["k", "o", "n", "n", "i", "c", "h", "i", "w", "a"]]
]
nested_map = nested.map { |a,b| [a,b.join] }
# => [[0.5623507523876472, "hello"],
# [0.07381531933500263, "hallo"],
# [0.49993338806153054, "nihao"],
# [0.6499234734532127, "konnichiwa"]]
If you want to destroy the source array nested
Use Arry#map! method :
nested = [
[0.5623507523876472, ["h", "e", "l", "l", "o"]],
[0.07381531933500263, ["h", "a", "l", "l", "o"]],
[0.49993338806153054, ["n", "i", "h", "a", "o"]],
[0.6499234734532127, ["k", "o", "n", "n", "i", "c", "h", "i", "w", "a"]]
]
nested.map! { |a,b| [a,b.join] }
# => [[0.5623507523876472, "hello"],
# [0.07381531933500263, "hallo"],
# [0.49993338806153054, "nihao"],
# [0.6499234734532127, "konnichiwa"]]
I need to create / generate long string contains permutation of characters and numbers at the same time I need to control the string length the most famous examples of this approach are
Metasploit project :
pettern_create.rb [string length as arg]
ex. pattern_create.rb 100
and
Ronin project:
String.generate([:alpha, 1], :numeric).take(100).each do |pattern|
print pattern
end
both will generate
A0A1A2A3A4A5A6A7A8A9B0B1B2B3B4B5B6B7B8B9C0C1C2C3C4C5C6C7C8C9D0D1D2D3D4D5D6D7D8D9E0E1E2E3E4E5E6E7E8E9F0F1F2F3F4F5F6F7F8F9G0G1G2G3G4G5G6G7G8G9H0H1H2H3H4H5H6H7H8H9I0I1I2I3I4I5I6I7I8I9J0J1J2J3J4J5J6J7J8J9
I tried with
all = ["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",
"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",
"0","1", "2", "3", "4", "5", "6", "7", "8", "9"]
puts all.permutation(4).to_a
puts this will take a huge time because it'll generate ALL permutations without control, the control is the way to prevent unwanted strings
there is no issue in specifying the particular position of a string like "4C5C6"
I can use
str = "A0A1A2A3A4A5A6A7A8A9B0B1B2B3B4B5B6B7B8B9C0C1C2C3C4C5C6C7C8C9D0D1D2D3D4D5D6D7D8D9E0E1E2E3E4E5E6E7E8E9F0F1F2F3F4F5F6F7F8F9G0G1G2G3G4G5G6G7G8G9H0H1H2H3H4H5H6H7H8H9I0I1I2I3I4I5I6I7I8I9J0J1J2J3J4J5J6J7J8J9"
puts str.index("4C5C6") #=> 46
Notes:
permutation should be generated with same sequence all the time.
I don't want to force user to gem huge project for small function
I need to understand the algorithm or programmatic trick to do that
Thanks
The permutation method results in a enumerator, which is what you want. Don't turn it into an array with to_a, just take what you need.
all = ["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",
"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",
"0","1", "2", "3", "4", "5", "6", "7", "8", "9"]
p all.permutation(4).first(100) #take(100) is fine too
Ruby strings work in a Range btw, so you can do:
('aaaa'..'zzzz').first(100) #or
('A0'..'Z9').first(100).join
#=> "A0A1A2A3A4A5A6A7A8A9B0B1B2B3B4B5B6B7B8B9C0C1C2C3C4C5C6C7C8C9D0D1D2D3D4D5D6D7D8D9E0E1E2E3E4E5E6E7E8E9F0F1F2F3F4F5F6F7F8F9G0G1G2G3G4G5G6G7G8G9H0H1H2H3H4H5H6H7H8H9I0I1I2I3I4I5I6I7I8I9J0J1J2J3J4J5J6J7J8J9"