Javascript: How to delete specific character values within strings within an array - javascript

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.

Related

What meaning the dash in array when iterating an array in for of loop with entries iterator?

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.

accessing multiple values of array and returning them concatenated or as string

const arr = ['a','c','o','l','s','t','r','i','n','g'];
let str = arr[1,2,2,3];
//returns l
What can i do to efficiently return "cool" which is what i want?
technically I'm doing this with all of the special characters as a way to reference them in string functions cause my code kept breaking otherwise.I found this fast, easy, and efficient;
The only reasonable solution I can think of is to capitalize the array and create a function with the lowered case and have that return a concatenated version. Am hoping for a better suggestion;
---update i just did this:
function Spc(...theArgs) {
let str = ""
theArgs.forEach(function(element){ str += spc[element]; });
return str;
}
findbar.value = Spc(0,10,12)+".*"+Spc(10,12,1);
You need to take the indices and map the characters. Then join the array to a string.
const
array = ['a', 'c', 'o', 'l', 's', 't', 'r', 'i', 'n', 'g'],
indices = [1, 2, 2, 3],
string = indices.map(i => array[i]).join('');
console.log(string);
If you have an array of the indexes of the characters in 'arr', you can create a string as following:
const arr = ['a','c','o','l','s','t','r','i','n','g'];
const indexes = [1,2,2,3]
const concatenated = indexes.map(el => arr[el]); // result: ['c', 'o', 'o', 'l']
const string = concatenated.join(''); // result 'cool'
Well since you prefer hard code here is what you can do to generate the string "cool". We simply create a new array of hard coded index values that generates the cool array and simply join them together!
const arr = ['a','c','o','l','s','t','r','i','n','g'];
let newArr = [arr[1],arr[2],arr[2],arr[3]];
newArr will be [c,o,o,l]
let string = newArr.join("");
string will be join with no spaces returning "cool"
Use a loop to access the array elements at each index and append them to the result string.
const arr = ['a','c','o','l','s','t','r','i','n','g'];
let str = '';
[1, 2, 2, 3].forEach(index => str += arr[index]);
console.log(str);

What is the best way to label user-inputted arrays?

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])
}

create two differents variables from the same array [duplicate]

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();

Regular Expression Alternatives (All Matches)

thanks for looking at my question.
I have a long list of alternatives that I am trying to match in a regex:
var re = new RegExp('o1|o2|o3|o4|o5|...','g')
The problem that I run into is what happens if o1 is a substring of o2. For example
var re = new RegExp('a|b|c|ab|abc','g')
var s = 'abc'
s.match(re) -> ["a", "b", "c"]
I would like for it to also be able to match the "ab" and "abc". I realize if I change the ordering of the RegExp, I can get it to match the longer string, but I really want to get all matches.
What is the best way to do this? This doesn't necessarily seem like the best (or a good way) of dealing with a long list of alternatives. I thought of testing each alternative with its own regexp, but that seemed less efficient.
Any guidance would be great. Thanks!
If you have only the long list of alternatives in your RegExp the better way to do it is using the indexOf method of String. Here is the code which outputs indexes of all alternatives in the string:
var alternatives = ['a', 'b', 'c', 'ab', 'abc'],
s = 'abc, cba',
i,
index;
for (i = 0; i < alternatives.length; i++) {
index = -1;
do {
index = s.indexOf(alternatives[i], index+1);
if (index !== -1) {
console.log(alternatives[i], index);
}
} while (index !== -1);
}
If you try to match the whole string like "abc" then the Rgex would be:
^(a|b|c|ab|abc)$
But there is maybe an easier way, but to help you, I have to know all "alternatives" you like to check for. Maybe a shorter regex expression is possible.
You could setup multiple (capturing groups) to get all matches... You still need to order your alternatives accordingly
Using your example:
var re = /((a)(b))(c)|(a)(b)|a|b|c/
var s5 = 'abc';
var s4 = 'ab';
var s3 = 'a';
var s2 = 'b';
var s1 = 'c';
console.log(s5.match(re)); // ['abc', 'ab', 'a', 'b', 'c', undef, undef]
console.log(s4.match(re)); // ['ab', undef, undef, undef, undef, 'a', 'b']
console.log(s3.match(re)); // ['a', ... undef x 6 ...]
console.log(s2.match(re)); // ['b', ... undef x 6 ...]
console.log(s1.match(re)); // ['c', ... undef x 6 ...]
More info on capturing groups

Categories

Resources