How to get multiple elements from an Array? - discord.js

I'm using discord.js and I want to create a "server" with passcode. I want the passcode to be 6 letters long, so far I can only do one.
It has to be random as well. Like "ZSHWJK" Instead of "AAAAAA"
Code:
var serverPasscode = ["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"]
module.exports = {
name: "createserver",
description: "Creates a server",
run(message, args, client){
const newServer = new MessageEmbed()
.setTitle(`${message.author.name}'s server`)
.setFooter(`${serverPasscode[Math.floor(Math.random() * serverPasscode.length)]}`)
message.channel.send(newServer);
}
};
Right now this can only return one element which is not what I want.

You could use a for loop and create a function such as this:
function makeGuildPassword(length) {
var result = ''; // create empty string that you will add random characters to
var characters = // list of characters (you can change this however you want)
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < length; i++) { // create a loop
// add a random character to the string; restart the loop
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
};
console.log(makeGuildPassword(6))

Related

How to do iterated moves of items in an array in Swift

Let's say we have an array:
var scrambledAlphabet = ["B", "C", "D", "E", "H", "F", "G", "A"]
and we want sort it by moving two items: item 7 ("A") to location 0, and item 4 ("H") to 7, described with an array of tuples:
var moves = [(7, 0), (4, 7)]
So, the desired result is:
["A", "B", "C", "D", "E", "F", "G", "H"]
Spontaneous that would be easy solved with this:
var scrambledAlphabet = ["B", "C", "D", "E", "H", "F", "G", "A"]
var moves = [(7, 0), (4, 7)]
for (i, j) in moves {
scrambledAlphabet.insert(scrambledAlphabet.remove(at: i), at: j)
}
print(scrambledAlphabet)
But it doesn't work. The output is:
["A", "B", "C", "D", "H", "F", "G", "E"]
The problem is that once the first item is moved, the index of the next item is altered. So, what would be the best way to tackle this? I find this surprisingly hard to crack. Any help is appreciated.
The restriction is that the two variables, scrambledAlphabet and moves, must be able to grow to any number.
And also one important note, the move-to-index (second number in the tuple) is referring to the old array, not the newly created. So, the inputs ["B", "C", "E", "D", "H", "F", "G", "A"] and [(7, 0), (4, 7), (3, 2)] should result in:
["A", "B", "C", "D", "E", "F", "G", "H"]
Sorry about the confusion about this last bit.
I thought of this (IMO a little clumsy) solution:
var newArray = Array(repeating: "", count: scrambledLetters.count)
for (start, end) in moves {
newArray[end] = scrambledLetters[start]
scrambledLetters[start] = ""
}
var scrambledLetterIndex = -1
func setScrambledLetterIndexToNextNonEmptyString() {
scrambledLetterIndex += 1
while scrambledLetterIndex < scrambledLetters.count - 1 && scrambledLetters[scrambledLetterIndex].isEmpty {
scrambledLetterIndex += 1
}
}
for i in newArray.indices {
if newArray[i] == "" {
setScrambledLetterIndexToNextNonEmptyString()
newArray[i] = scrambledLetters[scrambledLetterIndex]
}
}
scrambledLetters = newArray
Essentially, I first created a new array, and "took out" the strings that needs to be moved, and placed them in the correct position in the new array. That's what the first for loop did.
After the first for loop, the two arrays will look like this:
scrambledLetters: ["B", "C", "D", "E", "", "F", "G", ""]
newArray: ["A", "", "", "", "", "", "" , "H"]
Then, I slowly copied each non-empty item in the scrambled letters array into the new array's empty places.
Because this solution makes use of the empty string, it won't work if the input domain contained empty strings. If that's the case, you'd have to use something like a [String?].
A possible approach is to use an array of all indices which are not the source of any move. Then we can fill the destination sequentially, either from one of the moves, or from one of the “other indices”:
func scramble<T>(array: [T], moves: [(Int, Int)]) -> [T] {
// Moves sorted by increasing destination index:
var moves = moves.sorted(by: { $0.1 < $1.1 })
// All indices which are not the source of a move:
let sourceIndices = Set(moves.map { $0.0 })
var otherIndices = array.indices.filter { !sourceIndices.contains($0)}
// Fill each position with an element of a move source,
// or one of the "other" array elements:
return array.indices.map {
if let (from, to) = moves.first, $0 == to {
moves.removeFirst()
return array[from]
} else {
return array[otherIndices.removeFirst()]
}
}
}
Example 1:
print(scramble(array: ["B", "C", "D", "E", "H", "F", "G", "A"],
moves: [(7, 0), (4, 7)]))
// ["A", "B", "C", "D", "E", "F", "G", "H"]
Example 2:
print(scramble(array: [0, 1, 2, 3, 4, 5, 6, 7],
moves: [(1, 6), (7, 2), (3, 5), (5, 3), (4, 7)]))
// [0, 2, 7, 5, 6, 3, 1, 4]
I solved it by couple the items in the array with their original index, and sorted the moves so that the inserts doesn't scramble the order. Also moved all code into an array extension:
extension Array where Element : Equatable {
mutating func moveItem(from fromIndex: Int, to toIndex: Int) {
self.insert(self.remove(at: fromIndex), at: toIndex)
}
func performIteratedMoves(_ moves: [(Int, Int)]) -> [Element] {
var array = self
let enumeratedArray = array.enumerated().map{ (index: $0, item: $1) }
let sortedMoves = moves.sorted { $0.1 > $1.1 }
for (i, j) in sortedMoves {
guard let (_, item) = enumeratedArray.first(where:{ $0.index == i }), let correctIndex = array.firstIndex(where:{ $0 == item }) else { continue }
array.moveItem(from: correctIndex, to: j)
}
return array
}
}
Usage:
var scrambledAlphabet = ["B", "C", "E", "D", "H", "F", "G", "A"]
var moves = [(7, 0), (4, 7), (3, 2)]
print(scrambledAlphabet.performIteratedMoves(moves))
// ["A", "B", "C", "D", "E", "F", "G", "H"]

How to generate random string form array of elements by compared with another array of elements in swift?

I aware to get random character from a string. From here is the code,
func randomString(_ length: Int) -> String {
let master = Array("abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ_123456789".characters) //0...62 = 63
var randomString = ""
for _ in 1...length{
let random = arc4random_uniform(UInt32(master.count))
randomString.append(String(master[Int(random)]))
}
return randomString
}
Usage :
var randomArray1 = [String]()
for _ in 0...62{
randomArray1.append(self.randomString(1))
}
Here, If randomArray1.append(self.randomString(x)), then x = 1...N
Checking repeated elements :
var sameElementCatcher = [String]()
for x in 0...62{
let element = randomArray1[x]
randomArray1[x] = ""
if randomArray1.contains(element){
sameElementCatcher.append(element)
}
}
print("Same Elements")
print(sameElementCatcher.count != 0 ? sameElementCatcher : "Array count is zero")
Output:
Same Elements
["_", "u", "8", "7", "E", "P", "u", "y", "C", "-", "C", "x", "l", "j",
"t", "D", "U", "2", "e", "2"]
But I need to get array of 62 unique random characters from master by compared with randomArray1. i.e., Array count is zero
How can I achieve this without delay?
Note:
Also, I read this post also I have a answer for shuffling array. But this post different from shuffling only, Please, see usage.
Did you try like this?
What I understand from your question. generate a random text where all the characters are unique.
Before appending your random string to your array check is array have that char then append into your array.
func randomString(_ length: Int) -> String {
let master = Array("abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ_123456789".characters) //0...62 = 63
var randomString = ""
for _ in 1...length{
let random = arc4random_uniform(UInt32(master.count))
randomString.append(String(master[Int(random)]))
}
return randomString
}
var randomArray1 = [String]()
var tempRandomString = ""
let totalRandomCount = 62
var randomArrayCount = 0
while (totalRandomCount > randomArrayCount) {
tempRandomString = randomString(1)
if !randomArray1.contains(tempRandomString) {
randomArray1.append(tempRandomString)
randomArrayCount+=1
}
}
print(randomArray1)
Output: ["X", "u", "j", "1", "n", "E", "D", "q", "U", "6", "T", "O", "f", "J", "i", "c", "W", "V", "G", "R", "k", "7", "_", "8", "-", "l", "w", "4", "e", "Q", "C", "m", "M", "Y", "o", "S", "B", "2", "Z", "P", "p", "N", "y", "H", "a", "h", "z", "s", "b", "A", "3", "g", "x", "L", "v", "F", "d", "r", "t", "K", "9", "5"]
I tried this with playground. For this output 199 times loop executed.
If anyone knows better than this update yours.

Iterate through array and start a new array whenever a certain value is found

Say i have the following array:
array = ["a", "b", "c", "new", "d", "e", "f", "g", "new", "h", "i", "new"]
I want to create a new array every time I find the value "new".
So I would end up with:
array1 = ["a", "b", "c"]
array2 = ["d", "e", "f", "g"]
array3 = ["h", "i"]
What would be the best way to do this?
As the name implies you can split arrays with the split function, however that returns ArraySlice objects.
To get arrays back from the slices you need to map them (credits to Martin R)
let array = ["a", "b", "c", "new", "d", "e", "f", "g", "new", "h", "i", "new"]
let splittedArrays = array.split(separator: "new").map(Array.init)

How to "or" all elements in the range of an array

I am trying to say if x == consonants[0] or [1] or [2] all the way to [21] on one line. For some reason I thought consonants[0..21] would work but it doesn't:
consonants = ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t",
"v", "w", "x", "y", "z"]
new_first = ["m", "a", "t", "t", "h", "e", "w", "s"]
new_first.each do |x|
if x == consonants[0]
puts x.next!
elsif x == consonants[1]
puts x.next!
elsif x == consonants[2]
puts x.next!
elsif x == consonants[3]
puts x.next!
else
puts "test failed"
end
end
There's several ways to crack this nut, but it depends on your performance concerns, and how extensible this needs to be. Normally a chain of if statements which are of the form x == y and x == z can be folded into:
case (x)
when y, z
# ... Executed on a match
end
In your case you can even do this by using your array as a list of valid values:
case (x)
when *constants
puts x.next!
end
For larger lists you might want to fold this up into a Set since these are optimized for include? tests:
consonants_set = Set.new(consonants)
if (consonants_set.include?(x))
puts x.next!
end
Since you're doing single letter matches you have a lot more options. For example, a regular expression:
consonants_regexp = Regexp.new('[%s]' % consonants.join)
if (consonants_regexp.match(x))
puts x.next!
end
Or you can even do a simple substring match:
consonants_string = consonants.join
if (consonants_string[x])
puts x.next!
end
Worth noting but you can iterate over the characters in strings:
'cwzbrly'.each_char do |c|
puts c
end
That avoids the need to create and/or type in long arrays of the form [ 'a', 'b', ... ].
You can do this:
if consonants.include? (x)
your-code-here
end
This will check if there's an element equal to x inside the array.
You can use regular expression
if x =~ /[aeiou]/
puts 'test failed'
else
puts x.next!
end
/[aeiou]/ is saying match anything that is a, e, i, o, or u.
This will eliminate the need to create an array of consonants.
If I correctly understand and you're expecting nuuixt as a result, you can do:
new_first.select { |letter| consonants.include?(letter) && letter.next! }
&& works here this way: if consonants.include?(letter) evaluates to true then block return letter.next! .
Consider this:
consonants = ('a' .. 'z').to_a - %w[a e i o u] # => ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z"]
shifted_consonants = consonants.zip(consonants.rotate).to_h # => {"b"=>"c", "c"=>"d", "d"=>"f", "f"=>"g", "g"=>"h", "h"=>"j", "j"=>"k", "k"=>"l", "l"=>"m", "m"=>"n", "n"=>"p", "p"=>"q", "q"=>"r", "r"=>"s", "s"=>"t", "t"=>"v", "v"=>"w", "w"=>"x", "x"=>"y", "y"=>"z", "z"=>"b"}
'matthews'.chars.map{ |c| shifted_consonants[c] || c } # => ["n", "a", "v", "v", "j", "e", "x", "t"]
That took the range of 'a' to 'z' and converted it to an array, then subtracted the array of vowels, resulting in only consonants.
Next, it turned the array of consonants into a hash/look-up table shifted_consonants where each key is a current consonant and the value is the next consonant.
Finally, it takes each character in 'matthews' and looks to see if there is a value in shifted_consonants for that character. If not, nil is returned, which triggers || and returns the current character. If there is a hit in the hash, the next value for that consonant is returned, which short-circuits the || "or".
An alternate would be to take advantage of tr:
consonants = (('a' .. 'z').to_a - %w[a e i o u]).join # => "bcdfghjklmnpqrstvwxyz"
shifted_consonants = consonants.chars.rotate.join # => "cdfghjklmnpqrstvwxyzb"
'matthews'.tr(consonants, shifted_consonants).chars # => ["n", "a", "v", "v", "j", "e", "x", "t"]
Checking for speed:
CONSONANTS = ('a' .. 'z').to_a - %w[a e i o u] # => ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z"]
SHIFTED_CONSONANTS_HASH = CONSONANTS.zip(CONSONANTS.rotate).to_h # => {"b"=>"c", "c"=>"d", "d"=>"f", "f"=>"g", "g"=>"h", "h"=>"j", "j"=>"k", "k"=>"l", "l"=>"m", "m"=>"n", "n"=>"p", "p"=>"q", "q"=>"r", "r"=>"s", "s"=>"t", "t"=>"v", "v"=>"w", "w"=>"x", "x"=>"y", "y"=>"z", "z"=>"b"}
CONSONANTS_STR = (('a' .. 'z').to_a - %w[a e i o u]).join # => "bcdfghjklmnpqrstvwxyz"
SHIFTED_CONSONANTS_STR = CONSONANTS_STR.chars.rotate.join # => "cdfghjklmnpqrstvwxyzb"
require 'fruity'
sample_string = 'matthews'
compare do
use_hash { sample_string.chars.map{ |c| SHIFTED_CONSONANTS_HASH[c] || c } }
use_tr { sample_string.tr(CONSONANTS_STR, SHIFTED_CONSONANTS_STR).chars }
end
# >> Running each test 2048 times. Test will take about 1 second.
# >> use_tr is faster than use_hash by 10.000000000000009% ± 10.0%
The longer the sample string is, the greater the difference. Changing to:
sample_string = 'matthews' * 1000
I see a result of:
# >> Running each test 4 times. Test will take about 1 second.
# >> use_tr is faster than use_hash by 4x ± 0.1
Found in a comment, NOT in the question where it belongs...
my goal is to change the constonant to the next consonant and the vowel to the next vowel for the arraynew_first = ["m", "a",
Adjusting for that here's some changes. You can unravel the deltas:
ALPHABET = ('a' .. 'z').to_a
VOWELS = %w[a e i o u]
CONSONANTS = ALPHABET - VOWELS # => ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z"]
SHIFTED_CONSONANTS = CONSONANTS.rotate # => ["c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z", "b"]
SHIFTED_VOWELS = VOWELS.rotate # => ["e", "i", "o", "u", "a"]
SHIFTED_CONSONANTS_HASH = CONSONANTS.zip(SHIFTED_CONSONANTS).to_h # => {"b"=>"c", "c"=>"d", "d"=>"f", "f"=>"g", "g"=>"h", "h"=>"j", "j"=>"k", "k"=>"l", "l"=>"m", "m"=>"n", "n"=>"p", "p"=>"q", "q"=>"r", "r"=>"s", "s"=>"t", "t"=>"v", "v"=>"w", "w"=>"x", "x"=>"y", "y"=>"z", "z"=>"b"}
SHIFTED_VOWELS_HASH = VOWELS.zip(SHIFTED_VOWELS).to_h # => {"a"=>"e", "e"=>"i", "i"=>"o", "o"=>"u", "u"=>"a"}
sample_string = 'matthews'
sample_string.chars.map{ |c| SHIFTED_CONSONANTS_HASH[c] || SHIFTED_VOWELS_HASH[c] } # => ["n", "e", "v", "v", "j", "i", "x", "t"]
CONSONANTS_STR = CONSONANTS.join # => "bcdfghjklmnpqrstvwxyz"
SHIFTED_CONSONANTS_STR = SHIFTED_CONSONANTS.join # => "cdfghjklmnpqrstvwxyzb"
SHIFTED_VOWELS_STR = SHIFTED_VOWELS.join # => "eioua"
CHARACTERS_STR = (CONSONANTS + VOWELS).join # => "bcdfghjklmnpqrstvwxyzaeiou"
SHIFTED_CHARACTERS_STR = SHIFTED_CONSONANTS_STR + SHIFTED_VOWELS_STR # => "cdfghjklmnpqrstvwxyzbeioua"
sample_string.tr(CHARACTERS_STR, SHIFTED_CHARACTERS_STR).chars # => ["n", "e", "v", "v", "j", "i", "x", "t"]
The changes won't affect the speed of the actual code: tr would still outrun using the hash lookups.

Swift live text field checking for characters from multiple arrays [duplicate]

This question already has answers here:
Check password string strength criteria in Swift
(2 answers)
Closed 6 years ago.
I have a text field which will serve as a password input. I have created 4 arrays
upperCaseAll = ["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"]
lowerCaseAll = ["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"]
numberAll = [1 ,2, 3, 4, 5, 6, 7, 8, 9, 0]
specialCharAll = ["-", "/", ":", ";", "(", ")", "$", "&", "#", "\"", ".", ",", "?", "!", "'", "[", "]", "{", "}", "#", "%", "^", "\\", "|", "~", "<", ">", "€", "£", "¥", "•", ".", ","]
I am trying to make the user type at least one of each type of character.
I have 4 text views that will turn from red to green once each rule is met.
Then when all rules are met the red text views turn green and the login button is enabled
My question is how do I live check the text field to see if it has satisfied a rule? I imagine it would have to check each of the arrays overtime a character is entered
Oh also should the numbers be Ints or Strings?
Thanks
It's easier if you use Set instead of Array. Here's an example:
private let upperCaseAll = Set("ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters)
private let lowerCaseAll = Set("abcdefghijklmnopqrstuvwxyz".characters)
private let numberAll = Set("0123456789".characters)
private let specialCharAll = Set("-/:;()$&#\".,?!'[]{}#%^\\|~<>€£¥".characters)
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Determines what the new value of the text field will be
let newText = range.length == 0 ? textField.text! + string : (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
// Turn that string into a Set of Characters
let characters = Set(newText.characters)
let hasUpperCase = !characters.intersect(self.upperCaseAll).isEmpty
let hasLowerCase = !characters.intersect(self.lowerCaseAll).isEmpty
let hasNumber = !characters.intersect(self.numberAll).isEmpty
let hasSpecialChar = !characters.intersect(self.specialCharAll).isEmpty
// Now turn your 4 other views to green/red as needed
print("hasUpperCase = \(hasUpperCase), hasLowercase = \(hasLowerCase), hasNumber = \(hasNumber), hasSpecialChar = \(hasSpecialChar)")
...
return true
}
You can do it using the UITextFieldDelegate
See Apple Docs - textField(_:shouldChangeCharactersInRange:replacementString:)
The text field calls this method whenever user actions cause its text
to change. Use this method to validate text as it is typed by the
user. For example, you could use this method to prevent the user from
entering anything but numerical values.
But you should think about using a regex to check the password string. That would be more convenient.

Resources