Regular Expressions looping issue - javascript

I am creating a javascript(Node.js) looping function that is supposed to iterate through an array of strings, then return true or false when tested against a regular expression. If FALSE, return the value immediately (breaking the loop). However, the second value in the array still returns false, although it is valid.
The calling function passes these values:
var valuesArray = ["ABCXYZ", "ABCXYZ1"];
var regexValue = /[a-zA-Z0-9]+$/;
var regex = new RegExp(regexValue);
function validateArrayValues(valuesArray, regex) {
var regexResult, item;
for (let counter = 0; counter < valuesArray.length; counter++) {
item = valuesArray[counter];
regexResult = regex.test(item);
if (!regexResult) return false;
}
return true;
}

Work correctly, anything else you removed to keep the example simple?
var valuesArray = ["ABCXYZ", "ABCXYZ1"];
var regexValue = /[a-zA-Z0-9]+$/;
var regex = new RegExp(regexValue);
function validateArrayValues(valuesArray, regex) {
var regexResult, item;
for (let counter = 0; counter < valuesArray.length; counter++) {
item = valuesArray[counter];
regexResult = regex.test(item);
if (!regexResult) return false;
}
return true;
}
console.log(validateArrayValues(valuesArray, regex));

Related

Common Character Count in Strings JavaScript

Here is the problem:
Given two strings, find the number of common characters between them.
For s1 = "aabcc" and s2 = "adcaa", the output should be 3.
I have written this code :
function commonCharacterCount(s1, s2) {
var count = 0;
var str = "";
for (var i = 0; i < s1.length; i++) {
if (s2.indexOf(s1[i]) > -1 && str.indexOf(s1[i]) == -1) {
count++;
str.concat(s1[i])
}
}
return count;
}
console.log(commonCharacterCount("aabcc", "adcaa"));
It doesn't give the right answer, I wanna know where I am wrong?
There are other more efficient answers, but this answer is easier to understand. This loops through the first string, and checks if the second string contains that value. If it does, count increases and that element from s2 is removed to prevent duplicates.
function commonCharacterCount(s1, s2) {
var count = 0;
s1 = Array.from(s1);
s2 = Array.from(s2);
s1.forEach(e => {
if (s2.includes(e)) {
count++;
s2.splice(s2.indexOf(e), 1);
}
});
return count;
}
console.log(commonCharacterCount("aabcc", "adcaa"));
You can do that in following steps:
Create a function that return an object. With keys as letters and count as values
Get that count object of your both strings in the main function
Iterate through any of the object using for..in
Check other object have the key of first object.
If it have add the least one to count using Math.min()
let s1 = "aabcc"
let s2 = "adcaa"
function countChars(arr){
let obj = {};
arr.forEach(i => obj[i] ? obj[i]++ : obj[i] = 1);
return obj;
}
function common([...s1],[...s2]){
s1 = countChars(s1);
s2 = countChars(s2);
let count = 0;
for(let key in s1){
if(s2[key]) count += Math.min(s1[key],s2[key]);
}
return count
}
console.log(common(s1,s2))
After posting the question, i found that i havent looked the example well. i thought it wants unique common characters ..
and i changed it and now its right
function commonCharacterCount(s1, s2) {
var count = 0;
var str="";
for(var i=0; i<s1.length ; i++){
if(s2.indexOf(s1[i])>-1){
count++;
s2=s2.replace(s1[i],'');
}
}
return count;
}
Create 2 objects containing characters and their count for strings s1
and s2
Count the common keys in 2 objects and return count - Sum the common keys with minimum count in two strings
O(n) - time and O(n) - space complexities
function commonCharacterCount(s1, s2) {
let obj1 = {}
let obj2 = {}
for(let char of s1){
if(!obj1[char]) {
obj1[char] = 1
} else
obj1[char]++
}
for(let char of s2){
if(!obj2[char]) {
obj2[char] = 1
} else
obj2[char]++
}
console.log(obj1,obj2)
let count = 0
for(let key in obj1 ){
if(obj2[key])
count += Math.min(obj1[key],obj2[key])
}
return count
}
I think it would be a easier way to understand. :)
function commonCharacterCount(s1: string, s2: string): number {
let vs1 = [];
let vs2 = [];
let counter = 0;
vs1 = Array.from(s1);
vs2 = Array.from(s2);
vs1.sort();
vs2.sort();
let match_char = [];
for(let i = 0; i < vs1.length; i++){
for(let j = 0; j < vs2.length; j++){
if(vs1[i] == vs2[j]){
match_char.push(vs1[i]);
vs2.splice(j, 1);
break;
}
}
}
return match_char.length;
}
JavaScript ES6 clean solution. Use for...of loop and includes method.
var commonCharacterCount = (s1, s2) => {
const result = [];
const reference = [...s1];
let str = s2;
for (const letter of reference) {
if (str.includes(letter)) {
result.push(letter);
str = str.replace(letter, '');
}
}
// ['a', 'a', 'c'];
return result.length;
};
// Test:
console.log(commonCharacterCount('aabcc', 'adcaa'));
console.log(commonCharacterCount('abcd', 'aad'));
console.log(commonCharacterCount('geeksforgeeks', 'platformforgeeks'));
Cause .concat does not mutate the string called on, but it returns a new one, do:
str = str.concat(s1[i]);
or just
str += s1[i];
You can store the frequencies of each of the characters and go over this map (char->frequency) and find the common ones.
function common(a, b) {
const m1 = {};
const m2 = {};
let count = 0;
for (const c of a) m1[c] = m1[c] ? m1[c]+1 : 1;
for (const c of b) m2[c] = m2[c] ? m2[c]+1 : 1;
for (const c of Object.keys(m1)) if (m2[c]) count += Math.min(m1[c], m2[c]);
return count;
}

I'm only able to return 1 array

I'm trying to take this array and split it into 2 new arrays, evens and odds and return them. When I run the code below I am only getting the odds, why is that? And what can I do to solve it?
Thanks in advance.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return(evens, odds);
}
divider(numbersArray);
Because JavaScript can only return one value. Ever.
return(evens, odds)
evaluates to the same value as
return odds
due to the comma operator wrapped in grouping parenthesis.
Perhaps returning an array of arrays (or even an object of arrays) is useful..
return [evens, odds]
You should return your results as an array.
return [evens, odds];
And then to access the results:
var evens;
var odds;
var arrayResults = divider(numbersArray);
evens = arrayResults[0];
odds = arrayResults[1];
console.log(evens);
console.log(odds);
In Javascript, you can only return ONE value. So, if you want to return multiples values, to separate them, you can put them in an array or in an object :
return([evens, odds]);
OR
return({evens: evens, odds: odds})
The result of evaluating (evens, odds) is odds, that is returned thus.
This is how comma operator works.
Use the following statement instead:
return { 'evens': evens, 'odds': odds };
As an example:
var v = divider(numberArrays);
v.evens; // get evens this way
v.odds; // get odds this way
You can return only one entity from a function. Its better to wrap your results in single object.
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens:evens, odds:odds};
}
divider(numbersArray);
Es5 doesn't support tuples, You should wrap your return
in an object like here
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens:evens,
odds:odds};
}
divider(numbersArray);
Or in an array as the other aswers show
You could return an object, like this:
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider( arr ) {
var evens = [];
var odds = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
evens.push(arr[i]);
} else {
odds.push(arr[i]);
}
}
return {evens, odds};
}
divider(numbersArray);

Returning multiple index values from an array using Javascript

I have an array containing the individual letters of a word and i want to search the array to return the index values of certain letters. However, if the word contains more a letter more than once (such as 'tree') the programme only returns one index value.
This is a sample of the code:
var chosenWord = "tree";
var individualLetters = chosenWord.split('');
var isLetterThere = individualLetters.indexOf(e);
console.log(isLetterThere);
this code will return the number '2', as that is the first instance of the letter 'e'. How would i get it to return 2 and 3 in the integer format, so that i could use them to replace items in another array using the .splice function.
indexOf takes a second parameter, as the position where it should start searching from.
So my approach would be:
function findLetterPositions(text, letter) {
var positions = new Array(),
pos = -1;
while ((pos = text.indexOf(letter, pos + 1)) != -1) {
positions.push(pos);
}
return positions;
}
console.log(findLetterPositions("Some eerie eels in every ensemble.", "e"));
http://jsfiddle.net/h2s7hk1r/
You could write a function like this:
function indexesOf(myWord, myLetter)
{
var indexes = new Array();
for(var i = 0; i < myWord.length; i++)
{
if(myWord.charAt(i) == myLetter)
{
indexes.push(i);
}
}
return indexes;
}
console.log(indexesOf("tree", "e"));
Loop through it as here:
var chosenWord = "tree";
var specifiedLetter = "e";
var individualLetters = chosenWord.split('');
var matches = [];
for(i = 0;i<individualLetters.length;i++){
if(individualLetters[i] == specifiedLetter)
matches[matches.length] = i;
}
console.log(matches);
An alternative using string methods.
var str = "thisisasimpleinput";
var cpy = str;
var indexes = [];
var n = -1;
for (var i = cpy.indexOf('i'); i > -1; i = cpy.indexOf('i')) {
n += i;
n++;
indexes.push(n);
cpy = cpy.slice(++i);
}
alert(indexes.toString());
var getLetterIndexes = function(word, letter) {
var indexes = [];
word.split("").forEach(function(el, i) {
el === letter && indexes.push(i);
});
return indexes;
};
getLetterIndexes("tree", "e"); // [2, 3]

Arrays Splice Pop Shift Read

I create an array like so
var membersList = $('#chatbox_members' , avacweb_chat.doc.body).find('li');
var onlineUsers = [];
var offLineUsers = [];
for(var i =0;i<membersList.length;i++){
var name = $(membersList[i]).text().replace("#","");
onlineUsers.push(name);
}
alert(onlineUsers);
listedUsers would come out something like so [Mr.EasyBB,Tonight,Tomorrow,Gone];
Question is if I use a two for loops one outside a setInterval and one inside to compare-
var membersList = $('#chatbox_members' , _chat.doc.body).find('li');
var onlineUsers = [];
var offLineUsers= [];
for(var i =0;i<membersList.length;i++){
var name = $(membersList[i]).text().replace("#","");
onlineUsers.push(name);
}
var int = setInterval(function() {
var newMember = ('#chatbox_members' , _chat.doc.body).find('li');
for(var i =0;i<newMember.length;i++){
var name = $(newMember[i]).text().replace("#","");
offLineUsers.push(name);
}
Which then would get:
onlineUsers = [Mr.EasyBB,Tonight,Tomorrow,Gone];
offLineUsers = [Mr.EasyBB,Tonight];
So to get the offline users I want to basically replace onlineUsers with offLineUsers which then should return Tomorrow,Gone . Though I know that an object doesn't have the function to replace so how would I go about this?
I don't think the splice function would work since you need to have parameters, and pop or shift are beginning and end of array.
for(var i = 0 ; i < offLineUsers.length ; i++)
{
for(var j = 0 ; j < onlineUsers.length ; j++)
{
if(onlineUsers[j] == offLineUsers[i])
{
onlineUsers.splice(j,1);
}
}
}
Try this snippet.
If I have understand well, maybe that helps:
function bus_dup() {
for(var i = 0; i < offLineUsers.length; i++) {
onLineUsers.splice(onLineUsers.indexOf(offLineUsers[i]),1);
}
offLineUsers = [];
}
This should do what you are looking for on a modern browser, using array.filter
var onlineUsers = ["Mr.EasyBB", "Tonight", "Tomorrow", "Gone"];
var offLineUsers = ["Mr.EasyBB", "Tonight"];
function discord(online, offline) {
return online.filter(function (element) {
return offline.indexOf(element) === -1;
});
}
console.log(discord(onlineUsers, offLineUsers));
Output
["Tomorrow", "Gone"]
On jsfiddle
If you want the difference regardless of the order of attributes passed to the function then you could do this.
var onlineUsers = ["Mr.EasyBB", "Tonight", "Tomorrow", "Gone"];
var offLineUsers = ["Mr.EasyBB", "Tonight"];
function difference(array1, array2) {
var a = array1.filter(function (element) {
return array2.indexOf(element) === -1;
});
var b = array2.filter(function (element) {
return array1.indexOf(element) === -1;
});
return a.concat(b);
}
console.log(difference(onlineUsers, offLineUsers));
console.log(difference(offLineUsers, onlineUsers));
Output
["Tomorrow", "Gone"] 
["Tomorrow", "Gone"] 
On jsfiddle

Array length undefined after split

I'd like to split a string ("1,2,3") and return it as an int array so I wrote the following function:
function stringToIntArray(string) {
var split = {};
split = string.split(',');
var selected = {};
for (var i = 0; i <= split.length; i++) {
selected[i] = split[i];
}
return selected;
}
However split.length is always undefinied. Where's my mistake?
var selected = {};
doesn't build an array but an object, which has no length property.
You can fix your code by replacing it with
var selected = [];
If you want to return an array of numbers, you can change your code to
function stringToIntArray(string) {
var split = string.split(',');
var selected = [];
for (var i = 0; i < split.length; i++) {
selected.push(parseInt(split[i], 10));
}
return selected;
}
Note that I replaced <= with < in your loop.
Note also that for modern browsers, you can use the map function to make it simpler :
function stringToIntArray(string) {
return string.split(',').map(function(v){ return parseInt(v, 10) });
}

Categories