I am creating a word generator like Awkwords that randomly picks a letter from a labelled array and puts it in a sequence.
I am currently just having the label be the first item of its array. Here's a simple version:
let sequence = 'CVC'
let word = ''
let consonants = ['C', 'b', 'c', 'd',]
let vowels = ['V', 'a', 'e', 'i',]
let lists = [consonants, vowels]
for (letter of sequence) {
for (list of lists) {
if (list[0] === letter) {
pick random letter out of the list other than its first value and add it to the word
}
}
}
I'm almost brand new to programming in general so I have no idea if this is the way I should be doing this. Is there a more efficient way to label an array?
There will be a max of 26 lists (one for each letter) and the items within them will change depending on what the user inputs.
One way to get something like a "labeled array" is to use a javascript object. Here you could use the letters as keys (or properties) and the associated list as the value. This would also save you looping through the lists to search for the desired letter.
Try something like below:
let sequence = "CVC";
let word = "";
let patterns = {
C: ["b", "c", "d"],
V: ["a", "e", "i"]
};
for (letter of sequence) {
// do something here with patterns[letter]
console.log(patterns[letter])
}
Related
If I normally use for of loop and use iterator as entries that situation look like this:
var a = ['a', 'b', 'c'];
var iterator = a.entries();
for (let e of iterator) {
console.log(e);
}
// [0, 'a']
// [1, 'b']
// [2, 'c']
iterator: will be the entire array that contain all elements key/value pair. Key will be the index.
e: will be an element in the array
BUT what is this??????
let text = "A A A";
let splitwords = text.split(" ");
let words = [];
for (const [, item] of splitwords.entries()) {
words.push(item.split(""));
}
console.log(`This is the words: ${words}`);
what meaning the [, item] part???
and why should i use this pattern?
text.split("") do exactly same thing or not?
(Otherwise I try solve an text animation problem and this inherit from that code:
framer motion text animation )
Thank you
PS: I know this is an array destructing my main question that why????
for (const [, item] of splitwords.entries()) {
words.push(item.split(""));
}
[, item] is called array destructing, and the reason for that is because of entries in splitwords.entries(). The result of that array is like this [0, "a"],[1, "b"] (the first item is an index, and the second item is value), but in this case, they don't use an index, so the declaration is like [,item] (If they want to use it, the code can be [index, item]).
Without using an index, they can implement this way
for (const item of splitwords) { //remove entries and array destructing
words.push(item.split(""));
}
and why should I use this pattern?
Well, I think this is just their code style to use for of for collecting both index and value together. It depends on you need an index or not.
words.push(item.split("")) is different from the above case, they try to make the entire word "Hello" into characters ["H","e","l","l","o"] for the animation, so the final result of words can be
[
["F","r","a","m","e"],
["M","o","t","i","o","n"],
...
]
It's just a way to skip destructuring the first element in the array. You are basically saying that you are not interested in the first array item.
Since the entries() method returns a new Array Iterator object that contains the key/value pairs for each index in the array.
const foo = ['a', 'b', 'c'];
for (const [, item] of foo.entries()) {
// item would be 'a', 'b', 'c'
}
for (const [index, item] of foo.entries()) {
// item would be 'a', 'b', 'c'
// index would be 0, 1, 2
}
This is a destructuring assignment.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Array.prototype.entries() returns an array of 2 elements for the index and the item itself for each array item.
So in this expression the index is assign to nothing (because there is no variable declared before the comma) and the item is assigned to item.
Example
const ar = [1,2]
const [,value2]=ar
console.log(value2)
const [value1,]=ar
console.log(value1)
const [v1, v2] = ar
console.log(v1, v2)
For the item.split("") it just seems useless, the result would be the same in the present case with just words.push(item) since each word is just one letter... If the words were more than one letter this would just store each letter separately in the words array. Which could maybe be called letters I guess...
Edit:
for the "why use this pattern" question. In the present case, again it just seems useless. The index is not used so calling entries just don't seems relevant.
I don't know if you 'should' use this pattern, but if you want an explanation of what it is, it's like
for(let temp of splitwords.entries()){
const [, item] = temp;
words.push(item.split('');
}
And then const [, item] = temp; is basically the same as const item = temp[1].
Due to how ".entries()" work for an array (giving [index, value]), since the index is ignored by the destructuring, the resulting item is just the value. So, I don't think the result is any different from the following:
for (const item of splitwords) {
words.push(item.split(""));
}
Maybe they were preparing for the future, in case the index becomes important some day.
Hello there I am trying to do a code wars kata: https://www.codewars.com/kata/54a91a4883a7de5d7800009c/train/javascript
I know what I have done is very long-winded but I wanted to do it step by step before I refactored it.
I have split the string input from the user
Filtered through the array just to get the number and converted it to a NUMBER
Incremented that number by 1
Changed number back to string
Now I want to add my string number to the original array but it doesn't work and I don't understand why :S
I know this is not the final answer to the kata but I am just trying things and wondered why this did not work...
function isNumeric(num){
return !isNaN(num)
}
function incrementString (string) {
const splitString = string.split("");
let numbers = Number(splitString.filter(el => isNumeric(el)).join("")); //[
'f', 'o', 'o', 'b',
'a', 'r', '0', '0',
'4', '2'
]
let incrementNumber = numbers +=1; // 43
let revertNumberToString = incrementNumber.toString(); // "43"
let test = splitString.push(revertNumberToString); // why can I not push the number 43 onto my original array?
console.log(test); // 11? why?
}
incrementString("foobar0042")
It does seem to be working correctly. If you check splitString again after you push to it then it will have all 11 items. That is where the number 11 is coming from. When you save a push to a variable it doesn't make a new array but rather it saves the length of the new array.
console.log(splitString)
// ["f", "o", "o", "b", "a", "r", "0", "0", "4", "2"]
let test = splitString.push(revertNumberToString);
console.log(splitString)
// ["f", "o", "o", "b", "a", "r", "0", "0", "4", "2", 43]
console.log(test); // 11? why?
Javascript push method adds the element to the array and returns the length, that's why you get 11 instead of the array itself. Reference
You could take a different approach by splitting the value into string and number part and take the length of the number part for later padding the value with leading zeroes.
function incrementString(value) {
const
string = (value.match(/\D+/) || [''])[0],
number = (value.match(/\d+/) || ['0'])[0];
return string + (+number + 1).toString().padStart(number.length, 0);
}
function assertEquals(a, b) {
console.log(a === b, a, b);
}
assertEquals(incrementString("foobar000"), "foobar001");
assertEquals(incrementString("foo"), "foo1");
assertEquals(incrementString("foobar001"), "foobar002");
assertEquals(incrementString("foobar99"), "foobar100");
assertEquals(incrementString("foobar099"), "foobar100");
assertEquals(incrementString(""), "1");
This question already has answers here:
Copy array by value
(39 answers)
Closed 3 years ago.
I've an array, and I want to create 2 differents variables from the same array but this variables must have different result. For example, an array of string : the first variable must contain this array, and the other variable must contains this values but sorted. But it's not working :
var letters = ['b', 'c', 'a']; // datas
const lettersUnsorted = letters; // i want the array like the var "letters"
const letterSorted = letters.sort(); // i want the array like the var "letters" but sorted
console.log(letterSorted); // OK => returns: ["a", "b", "c"]
console.log(lettersUnsorted); // KO => returns: ["a", "b", "c"] instead of ['b', 'c', 'a']
You should make a copy the array first because sort() method modifies the original array. You can make the copy of the array using slice()
var letters = ['b', 'c', 'a'];
const lettersUnsorted = letters;
const letterSorted = letters.slice().sort(); //this line is changed
console.log(letterSorted);
console.log(lettersUnsorted);
This is because the reference to the original letters array is maintained.
lettersUnsorted and letterSorted are both referencing to the letters variable. This is because letters is an array (which is technically an object), and in JavaScript, assigning another variable to it will result in assignment by reference (rather than assignment by value). Therefore, any operations or mutation to letters will result in both lettersUnsorted and letterSorted in having the same result as letters, due to the reference to letter.
You should create a shallow clone of the original letters array. This will allow you to safely carry out any mutation without affecting the other array. We can achieve this using ES6's spread syntax.
const letters = ['b', 'c', 'a'];
const lettersClone = [...letters].sort();
console.log(letters);
console.log(lettersClone);
you can use concat also.
var letters = ['b', 'c', 'a'];
const lettersUnsorted = letters;
const letterssorted = ([].concat(letters)).sort();
I am trying to remove punctuation from each string within an array, but this problem would exist for trying to delete any type of character within strings within an array.
I have attempted to create 3 loops:
The first loop iterates over each item in arrayA that I'm aiming to edit.
The second loop iterates through each character in each string in arrayA.
The third loop checks whether the character in arrayA matches any character in arrayB, and deletes it if it does.
Nothing is being deleted however, and I'm not sure why.
This is my code so far:
let arrayA = ['abc', 'def', 'ghi'];
let arrayB = ['a', 'e', 'i', 'o', 'u'];
arrayA.forEach((item) => {
for (let i=0; i < item.length; i++) {
for (let arrayBIndex = 0; arrayBIndex < arrayB.length; arrayBIndex++) {
item.replace(arrayB[arrayBIndex], '');
};
};
});
console.log(arrayA);
I have searched for other questions dealing with this, but I haven't been able to find any answers, specifically where the elements to delete are contained in another list. Thank you for your help.
You can generate regular expression using arrayB and then using array#map iterate through each word in arrayA and use string#replace to get rid of words from arrayB.
let arrayA = ['abc', 'def', 'ghi'],
arrayB = ['a', 'e', 'i', 'o', 'u'],
regExp = new RegExp(arrayB.join('|'), 'g'),
result = arrayA.map(word => word.replace(regExp, ''));
console.log(result);
Use Array.prototype.splice(), take a look on this:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
If you wish to follow with arrays, I would suggest to transform your strings into an array of characters and using array filter operator.
However you can probably achieve what you want to do with regular expressions
const arrayA = ['abc', 'def', 'ghi'];
const arrayB = ['a', 'e', 'i', 'o', 'u'];
const result = arrayA
.map(s => [...s]) // array of chars
.map(chars => chars.filter(ch=>!arrayB.includes(ch)).join(''))//filter out invalid char and transform back into string
console.log(result)
const result = arrayA.map(item => {
let replaced = "";
for(const char of item)
if(!arrayB.includes(char))
replaced += char;
return replaced;
});
Strings are immutable. Every mutation returns a new string instead of mutating the original.
Is there a convenient way to get say the first n number of indices from this array:
var alphabet = ['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'];
and store it in another array, say alphabet2 = ['a','b','c']; without having to brute force with a loop? Thanks
Use the slice method:
> var alphabet = ['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'];
> alphabet.slice(0,3)
["a", "b", "c"]