I don't understand the variable let number= 0 - javascript

I don't understand what's the use of let number= 0. Without it, the code still works
const countLetter = (sentence) => {
let number = 0;
for (const letter in sentence){
number = Number(letter)
}
return { number }
}
console.log(countLetter('the best day'))
I don't understant the purpose of let number = 0

The purpose of the initialization
let number = 0
is so that, if passed an empty string, countLetter returns {number: 0} instead of {number: undefined}.
This is not to say that the function posted makes any particular sense. Although not the question asked, changing the for loop to a for...of construct would at least process individual letters instead of their index in the string, but the purpose of the loop remains unclear.

Related

Javascript - find all possible strings

Looking for some tips to solve this problem. We have string chain
const str = "543163431154",
and array with numbers where elements are basically numbers taken from this string
const array = ["21154", "543123", "163421154"]
What I'm looking for is to find all possible strings
Was thinking to split our input string as first, then create variable to store single letters. Subsequently I could iterate over newly created array in some kind of reduce function, but tbh I have no right solution
Here's an algorithm,
From your array, create 5 arrays, each one with different order of the elements from the original array
Iterate over each array
For each element, check using regex if the str starts with it (^currentElement)
If it is, remove from your str the current element and continue to the next element
If it's not, continue to the next array from the 5 you created
If you reach the last index of every array and str starts with it, add the current array to the results.
Here you go, now because it's not a code writing site and it's not a specific code question I wont write it for you - but the above algorithm will work for you.
Edit: After a bit more reading I understood the problem a bit better, and boy was this fun!
const str = "14316342115414321154"
const array = ["21154", "143", "21154143", "1634", "163421154"]
const findAllCombinations = (str, match) => {
const result = match.reduce((acc, layer) => {
if(str.indexOf(layer) === 0) {
if(str.substring(layer.length).length > 0) {
const nextLayer = findAllCombinations(str.substring(layer.length), match).map(c => addToLayer(layer, c))
acc.push(...nextLayer)
} else {
acc.push(addToLayer(layer, ""))
}
}
return acc;
}, [])
return result
}
const addToLayer = (layer, add) => `:${layer}${add}`
console.log(findAllCombinations(str,array))

Finding the Anagrams of a word from a list- codewars question

I am pretty new to programming and I was solving a problem on code wars which is as follows:
Question:
Write a function that will find all the anagrams of a word from a list. You will be given two inputs a word and an array with words. You should return an array of all the anagrams or an empty array if there are none.
This is my code
function anagrams(word, words) {
let word_Array = word.split('').sort()
let total = []
for (x = 0; x<words.length; x++) {
if(words[x].split('').sort() === word_Array) {
total.push(words[x])
} return total
}
}
The result should look something like this
anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']) => ['aabb', 'bbaa']
I keep getting an empty array when I run my code. Please can someone tell me the error in my code. Thank you
Please take a look at the following snippet.
const sort = (word) => word.split('').sort().join('');
function anagrams(word, words) {
let token = sort(word);
let total = []
for (let x = 0; x < words.length; x++) {
if (sort(words[x]) === token) {
total.push(words[x])
}
}
return total
}
console.log(anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']));
You are on the right track but missed a few details.
As others have mentioned you cant just compare discrete arrays with ===. The best you can do is an element wise compare. You dont really need to this if you compare normal value types such as numbers, strings, bools, ect. If you join the sorted string back its much easier to compare using built in operators such as ===.
Your control logic is wrong. Notice how you are returning straight from the loop? It means that at most you would ever get one results since the loop cant iterative over the full loop condition.
You should always qualify your variable declarations with let/const. This was missing in the for loop and would declare x as a global.
Improvements
You could replace the for loop with a for of and not have to worry about indexing.
for (let w of words) {
console.log(w); // we no longer have to worry about words[i].
}
Even better you could replace the entire for and array.push logic with a simple array.filter
const sort = (word) => word.split('').sort().join('');
function anagrams(word, words) {
let token = sort(word);
return words.filter((w) => sort(w) === token);
}
console.log(anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']));
Array is Object in JavaScript, which is reference type.
So you can not use "===" to check whether two arrays are equals.
For example:
var array1=[1,2];
var array2=[1,2];
var result = array1 === array2;
the result will be false.
My suggestion is writing a new function to check whether two arrays are equals by comparing the items.
function areEquals(array1, array2){
if(array1.length!==array2.length){
return false;
}
for(var i in array1){
if(array1[i]!==array2[i]){
return false;
}
}
return true;
}

for loop skipping one item in array in javascript

I am trying to make a function that removes strings from an array if they include a character in a certain other list
Here is the code:
var possible = ["salutations", "goodbye", "thanks", "welcome"];
var incorrect = ["o"];
console.log(possible);
function narrowdown(possible, incorrect)
{
var templist = possible;
for (i in possible)
{
console.log(i + " " + possible[i]);
var array1 = possible[i].split("");
var common = array1.filter(value => incorrect.includes(value));
console.log(common)
if (common.length)
{
templist.splice(i, 1);
}
}
possible = templist;
}
narrowdown(possible, incorrect);
console.log(possible);
Here I am trying to remove all the words that include the letter o. I created a temporary array in the function because it has happened to me before that a for loop skips items altogether.
The code first logs the index of the item in the list and then the item itself.
Then it turns the word into an array and checks for overlap between it and the "incorrect" array. It does that correctly and logs the overlapping characters.
The issue seems to be that it skips over the "goodbye" item for some reason. It doesn't even process it.
Here is the output I am getting:
[ 'salutations', 'goodbye', 'thanks', 'welcome' ]
0 salutations
[ 'o' ]
1 thanks
[]
2 welcome
[ 'o' ]
[ 'goodbye', 'thanks' ]
First of all, for (i in possible) is a bad way of looping through an array since it retrieves the keys before the loop begins and it never updates that list of keys. Also, if someone assigns an attribute to the array, like possible.foo = 17, then your loop will also go through that. The issue you're having is that when you splice the array, everything else is shifted one to the left, changing their indices to be one less, so your new index actually skips over the next element. The fix is to use a conventional for loop and decrement i after splicing:
for (let i = 0; i < possible.length; i ++) {
// more code...
if (common.length) {
templist.splice(i, 1);
i --;
}
}
The problem is that the array is re-indexed when you splice. One solution is to iterate in reverse:
var possible = ["salutations", "goodbye", "thanks", "welcome"];
var incorrect = ["o"];
console.log(possible);
function narrowdown(possible, incorrect)
{
var templist = possible;
var i = possible.length;
while (i--)
{
console.log(i + " " + possible[i]);
var array1 = possible[i].split("");
var common = array1.filter(value => incorrect.includes(value));
console.log(common)
if (common.length)
{
templist.splice(i, 1);
}
}
possible = templist;
}
narrowdown(possible, incorrect);
console.log(possible);
The issue comes from the line tempList = possible which is an assignment by reference, meaning that when you do the splice operation you do it on both arrays at the same time.
Generally it is considered bad form to manipulate data like that anyway, you should have narrowDown return a value that you re-assign to possible instead of filtering them in place. If you do that you can also leverage some of the newer array methods:
var possible = ["salutations", "goodbye", "thanks", "welcome"];
var incorrect = ["o"];
function narrowdown(possible, incorrect)
{
return possible.filter(item => !incorrect.some(test => item.includes(test)))
}
possible = narrowdown(possible, incorrect);
console.log(possible);
using the .some will also exit early as soon as there is a match, instead of looping over all incorrect values and the entire string, boosting performance slightly
If you're looking for a less "imperative" version of this function, you can make use of Array.filter(), Array.some(), and String.includes() to make a one-liner function that does the trick (for formatting purposes, I split it in the multiple lines in the snippet below).
const possible = ['salutations', 'goodbye', 'thanks', 'welcome'];
function narrowDown(possible, incorrect) {
return possible.filter((value) => (
!incorrect.some((exclude) => (value.includes(exclude)))
));
}
console.log('["o"]', JSON.stringify(narrowDown(possible, ['o'])));
console.log('["a"]', JSON.stringify(narrowDown(possible, ['a'])));
console.log('["a", "o"]', JSON.stringify(narrowDown(possible, ['a', 'o'])));

Splitting an array of numbers and non-numbers into two separate arrays

I'm very new to javascript and I'm trying to create a function that takes a mixed input of numbers and then loops through the array in order to sort them into two newer arrays so I can manipulate them further.
So if I have an input of
1,a,2,b,3,c,4,d,
I want to make two new arrays of
1,2,3,4 and a,b,c,d
So far I've been able to split the input string at the comma, so that I now have
1a2b3c4d
all I need to be able to do now is just separate the numbers and non-numbers. I was thinking of using two loops: one that checks
if(isNan.array[n] == True )
and then trying to find a way to store the letters into a variable using the loop and then using another loop to do so for the numbers using another if function.
Is this how I should do it, and do you have any advice on how to go about it?
Edit:
I now have this code to check for letters:
if (isNaN(splitResult[L])) {
for (i = 0; i < splitResult; i++) {
letterArray.add(splitResult[L]);
L = L + 1
When I try to output the results to a box to count letters (using the variable L), nothing shows up. I doubt I've made a new array
just for completion, split the string into array first :)
let yourString = '1a2b3c4d';
let yourArray = yourString.split('');
let letterArray = [];
let numberArray = [];
yourArray.forEach(item => {
if(isNaN(item) && typeof item === 'string'){
letterArray.push(item);
}
else if(!isNaN(item) {
numberArray.push(item);
}
});
console.log(letterArray, numberArray);
All you need to do is loop through the array, you can use the Array prototypes forEach. Or you can use the normal for loop to check through each element of the array. You can now check if each element isNaN and then push into the right array appropriately. You can use the snippet below
const yourArray = ['1','a','2','b','3','c','4','d'];
const letterArray = [];
const numberArray = [];
yourArray.forEach((eachItem) => {
if(isNaN(eachItem)){
letterArray.push(eachItem);
} else {
numberArray.push(eachItem);
}
});
console.log(letterArray, numberArray);

Javascript for-loop returning "null" instead of my value

I'm trying to get the function below to return the average of all elements in array1, but I keep getting null as the result. I can't seem to figure out why.
var array1 = [46,73,-18,0,-442,779,5,1400];
var arrayAverage = function(arrayavg) {
for (var average = 0,answer=0, arrayavg = arrayavg.length;array1 > answer;answer++)
average +=parseInt(arrayavg[answer]);
var calc = average/arrayavg.length;
return calc
};
There are a number of errors, I don't have time to point them all out, hopefully the following is sufficient:
var array1 = [46,73,-18,0,-442,779,5,1400];
var arrayAverage = function(arrayavg) {
I don't know why you using a function expression rather than a function declaration. It doesn't affect the issue, but is more code to write. It's also good to give variables names that express what they are for, so given that the function expects an array:
function arrayAverage(array) {
then:
for (var average = 0,answer=0, arrayavg = arrayavg.length;array1 > answer;answer++)
It's not a good idea to pile all those variable declarations into the for condition, far better to separate concerns and only create variables that you need:
var total = 0;
Now iterate over the array to get the total value. The '{' brackets can be omitted, but it's clearer to include them:
for (var i=0, iLen=array.length; i<iLen; i++) {
total += array[i];
}
Now calculate the average and return it in one statement:
return total/iLen;
}
console.log(arrayAverage(array1)); // 230.375
You need to put brackets after your for loop
I was too fast to answer.
You are re-assigning the passed array to the length of the passed array.
arrayavg = arrayavg.length
this breaks everything.
in the for loop you have assigned arrayavg=arrayavg.length and in the body ,you are accessing average+=arrayavg[answer]. arrayavg is now a primitive type . it will return undefined.
And your loop condition is array1 > answer array1 is an array .you cant compare it like that.it will return false.
modified code.
var array1 = [46,73,-18,0,-442,779,5,1400];
var arrayAverage = function(arrayavg) {
var sum=0;
for (var i=0;i<arrayavg.length;i++)
sum +=parseInt(arrayavg[i]);
return sum/arrayavg.length;
};
You are comparing a number to your array in your for loop. You want to stop the for when answer is the same as array1 length.
Also, don't change your parameter array to its length if you want to get its values in the loop.
var array1 = [46,73,-18,0,-442,779,5,1400];
var arrayAverage = function(arrayavg) {
for (var average = 0,answer=0, len = arrayavg.length;len > answer;answer++)
average +=parseInt(arrayavg[answer]);
var calc = average/len;
return calc
};
And to call it:
arrayAverage(array1);
Your code has two problems in the for loop.
for (var average = 0,answer=0, arrayavg = arrayavg.length;array1 > answer;answer++)
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
First thing is you set arrayavg to arrayavg's length BUT in the next line you try to read the index of the array. Well you overwrote the array with a number! Not going to happen.
Second issue you are comparing an array 'array1' to a number 'answer' . What does that check do? Not what you think it is going. You want to be checking the length, but wouldn't you want to be checking the passed in array, not the hardcoded one?
I think the other answers (particularly RobG) have covered most of it. It might help to follow a couple of standard rules (that I use) for your loops:
1) Always have the index as the first declared element, the length of the array (for caching purposes) as the second, and any other variables after them.
2) Always use brackets to separate your loop code from the code in the rest of the function. That way you know when to return your averaged product (ie after the }).
So this is my slightly rewritten code of your problem:
for (var index = 0, len = arrayavg.length, avg = 0; index < len; index++) {
avg += parseInt(arrayavg[index], 10) / len;
}
return avg;
Note also that parseInt should contain a radix (in this case 10). You can leave it out but it's good practice to always include it.
By the way, here's an alternative to your function you might find useful that uses a functional approach using reduce:
var arrayAverage = function (arr) {
return arr.reduce(function (a, b) { return a + b; }) / arr.length;
}

Categories

Resources