 # Discussion, Questions, and Resources for Part 2 (JavaScript Basic Algorithms, Object-Oriented, and Functional Programming - April 2018 Cohort)

## TOPIC INFORMATION

This topic is for those of us who are participating in the April 2018 JavaScript Algorithms and Data Structures cohort. Even though this topic is mainly for those participating in the cohort, it’s totally ok for others to participate as desired. All are welcome! This topic covers the following sections of the fCC beta curriculum:

## RESOURCES

• Reference Material

• Books / Tutorials

• Courses / Classes

• Games

• Tools / Validators

5 Likes

## MEMBERS CONTINUED …

hey guys,

i’m on the Basic Data Structures: Iterate Through All an Array’s Items Using For Loops. I’m not sure why, but it looks like I have an extra array around my solution which is throwing it off.

``````function filteredArray(arr, elem) {
let newArr = [];
// change code below this line
for (let i = 0; i < arr.length; i++) {
if (arr[i].indexOf(elem) !== -1) {
arr.splice(i, 1);
newArr.push(arr);
}
}
// change code above this line
return newArr;
}

// change code here to test different cases:
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));
``````

any ideas where I’m off?

@nvrqt03 I think your logic in the code above is to determine if `elem` is in the subArray (`arr[i]`) and if it is, remove `arr[i]` from the original `arr`. When the loop finishes going through each subArray, you return what’s left in `arr` since all of the matching subArrays have been removed. Is this correct?

The way I thought about this one was to only add subArrays to `newArr` that don’t have `elem` in them. So, `if elem is not in arr[i] then add that arr[i] to newArr`. Does that make sense? I find it easier to reason through it this way as opposed to modifying the array I’m looping through and keeping track of how that works.

Here’s how I did it in case it helps to see my logic:

``````function filteredArray(arr, elem) {
let newArr = [];
// change code below this line

for (let indexArr = 0; indexArr < arr.length; indexArr++) {

// Create subArr variable to reuse as needed
let subArr = arr[indexArr];

// Check to see if elem is in subArr, if not, it will return -1
if (subArr.indexOf(elem) === -1) {

// Since elem is not in subArr, add subArr to newArr.
newArr.push(subArr);
}
}
// change code above this line
return newArr;
}
``````

I’m not sure how to complete the challenge using the logic you present. If you figure it out, please share it here so I (and others) can learn from it. 1 Like

@nvrqt03 I was able to pass the exercise using `splice()`.

``````function filteredArray(arr, elem) {
let newArr = [];
// change code below this line

for (let i = 0; i < arr.length; i++) {
if (arr[i].indexOf(elem) !== -1) {
arr.splice(i, 1);
i--; // account for array modification
}
}

newArr = arr;
// change code above this line
return newArr;
}

// change code here to test different cases:
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));
``````
2 Likes

great solutions guys! glad to see someone got splice to work. basically I was trying to say that if the element does NOT exist in the array -

``````if (arr[i ].indexOf(elem) !== -1
``````

then to splice them from the array. they will make their own new array of uh… undesirables? then we will push what’s left to the newArr and return that. however I noticed @smsguy927 you didn’t push to the new array, and I’m not sure how i- - ; works in this situation.

sorry for the late reply, I code early in the morning. usually I can get some coding in after work as well, or respond during work. It was busy yesterday though.

`splice()` modifies the array it is called on and it shifts the indexes of the array when no elements are replaced after splicing. `i--` accounts for this modification and ensures that `arr[i]` will point to the next element in the array in the next iteration. Then I assign what’s left in the initial array to the result array.

`if (arr[i].indexOf(elem) !== -1)`

@nvrqt03 This will return `true` if `elem` is in `arr[i]`.

`indexOf(elem)` either returns the index of the item in the array that matches `elem` or returns `-1` if there is no match.

In the above, you’re returning `true` if `arr[i].indexOf(elem)` does not equal `!== -1`, i.e. return `true` if `arr[i].indexOf(elem)` returns an index of a matched item in the array, or return `true` if it returns anything other than `-1`.

The following returns `true` if `elem` is NOT in `arr[i]`:

`if (arr[i].indexOf(elem) === -1)`

That’s how I’m reading this. Let me know if I’m wrong.

1 Like

`if (arr[i].indexOf(elem) === -1)`
if that returns true, then the element is not in the current sub-index. that is exactly what we’re looking for. so from here, you can skip all the slicing and splicing and just:
`newArr.push(arr[i])`

for (let i = 0; i < arr.length; i++) {
if (arr[i].indexOf(elem) === -1) {
newArr.push(arr[i]);
}
}

2 Likes

Here are my solutions for the first three algorithms:

Convert Celsius to Fahrenheit
``````function convertToF(celsius) {
return (celsius * (9/5)) + 32;
}
``````
Reverse a String

I came up with the following, which splits the string into an array of letters and then adds the letters to a new string using the `map()` function.

``````function reverseString(str) {
let newStr = "";
return str.split('').map(letter => newStr = letter + newStr)[newStr.length-1];
}
``````

However, after looking through the freeCodeCamp Algorithm Challenge Guide: Reverse a String topic, I realized that I overcomplicated this and should’ve looked to built-in functions instead:

``````function reverseString(str) {
return str.split('').reverse().join('');
}
``````
Factorialize a Number

I started with the following, using a for loop to loop through the range between num and one and then multiply the counter by the current result:

``````function factorialize(num) {
let result = 1;
for (let numIndex=num; numIndex > 0; numIndex--) {
result *= numIndex;
}
return result;
}
``````

However, after looking at the freeCodeCamp Algorithm Challenge Guide: Factorialize A Number topic, and watching the video on recursion listed in the guide and this part of another video on recursion, I came up with this, which is more difficult to understand, but cleaner overall:

``````function factorialize(num) {
if (num === 0) return 1;
return num * factorialize(num-1);
}
``````

The following is another version shared by @Kagerjay (freeCodeCamp Algorithm Challenge Guide: Factorialize A Number) that I like the best, once I wrap my head around recursion:

``````function factorialize(num) {
return num === 0 ? 1 : num * factorialize(num-1);
}
``````

This Recursion and Recursive Functions video does a great job of explaining how the above recursive factorialize function works.

Any thoughts on the above solutions? Did anyone do anything different or find helpful resources to learn more about these? 1 Like

for the first one, converting celsius to fahrenheit, I essentially got the same as you. I only let fahrenheit equal the celsius conversion, and returned fahrenheit.

reversing a string - i got your second solution.

factorialize - slightly different -

```function factorialize(num) {
if (num === 0 || num === 1)
return 1;
for (let i = num - 1; i >= 1; i–) {
num *= i;
}
return num;
}

I’ll definitely check out that recursion video!

Here are a couple others:

find the longest word in a string:

```function findLongestWordLength(str) {
let largestWord = 0;
str = str.split(’ ');
for (let i = 0; i < str.length; i++) {
if (str[i].length > largestWord) {
largestWord = str[i].length;
}
}
return largestWord;
}

return largest numbers in arrays:

```function largestOfFour(arr) {
let largestNumber = [0,0,0,0];
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; j++) {
if (arr[i][j] < 0) {
arr[i].sort(function (a, b) {
return a - b;
});
largestNumber[i] = arr[i];
}
if (arr[i][j] > largestNumber[i])
largestNumber[i] = arr[i][j];
}
}
return largestNumber;
}

I’m working on the Confirm the Ending challenge. I think I"m close, but its inconsistent. its finding anything, not just at the end.

function confirmEnding(str, target) {
// “Never give up and good luck will find you.”
// – Falcor
if (str.lastIndexOf(target) > 0) {
return true;
}
else {
return false;
}
}

1 Like

@nvrqt03 Thanks for sharing! Anyone else want to share or have comments on any of the solutions shared so far?

Here are my solutions for the next three algorithms.

Find the Longest Word in a String

For Of Loop
I like this one the best at this point in my understanding of JavaScript because it’s straightforward and there’s no unseen things happening.

``````function findLongestWordLength(str) {
let longest = 0;
let wordsArr = str.split(' ');

for (let word of wordsArr) {
if (word.length > longest) {
longest = word.length;
}
}
return longest;
}
``````

Filter()
This is similar to the `For Of Loop`, but it uses `filter()` instead. I’m not sure if there are benefits to doing it this way.

``````function findLongestWordLength(str) {
let longest = 0;
str.split(' ').filter(word => {if (word.length > longest) longest = word.length});
return longest;
}
``````

In the Javascript Coding Challenge #4: Find Longest Word (Freecodecamp), they mention using the `sort()` method. In the fCC Guide, they recommend two other ways, one using `reduce() and Math.max` and the other way is to solve this with recursion.

Return Largest Numbers in Arrays

filter() and map()
My first attempt returned the following:

``````function largestOfFour(arr) {

let largestArr = [];

// Apply (i.e. map) the following filter to each sub array within the array
arr.map(function(subArr) {

let largest = 0;

/*
Filter the largest number from each sub array
if the number is greater than the previous largest number
OR the number is less than zero and the previous largest number is zero
then set largest to num
*/
subArr.filter(num => {if (num > largest || (num < 0 && largest === 0)) largest = num});

// Push the largest number of the sub array to the largestArr array
largestArr.push(largest);

});

return largestArr;
}

``````

map() and reduce()
I was able to break it down more, which is close to the example in the Return Largest Numbers in Arrays fCC guide entry and less complicated than my first attempt:

``````function largestOfFour(arr) {

let largestArr = [];

arr.map(subArr =>
largestArr.push(subArr.reduce((previous, current) =>
previous > current ? previous : current)));

return largestArr;
}
``````
Confirm the Ending

slice()
This is what I ended up with for my first attempt.

``````function confirmEnding(str, target) {
return str.slice(str.length - target.length, str.length) === target;
}
``````

substr()
The Confirm the Ending fCC Guide entry suggests another (better) way to do this using `substr()`. Again, I need to remember to look for better, more appropriate built-in methods:

``````function confirmEnding(str, target) {
return str.substr(-target.length) === target;
}
``````

Hopefully, the more I do this the more likely it’ll be that I’ll pick more appropriate methods for my solutions. What do you all think? Does anyone have solutions that aren’t shown or mentioned above? 2 Likes

My solution for Return Largest Numbers in Arrays.

I use map() and ES6 spread operator (the 3 dots! … )

``````function largestOfFour(arr) {
return arr.map(chunk => Math.max(...chunk));

// arr.map() grabs subarrays (I call it chuck here) and call the Math.max function on it to find the largest number in each subarray.
}
``````

Hope this helps!

2 Likes

I found a great tool for debugging your JavaScript code. It also offers other languages like Python and Ruby.
Basically, it visualizes every single execution of the code to help you debugging.
Not only debugging, I got tons of help to understand JS functions better and faster while solving the Basic Algorithm Scripting section.

The link http://pythontutor.com/visualize.html#mode=edit

3 Likes

@NariRoh Yes! That is a very elegant solution and it’s backed up by the curriculum in the ES6: Use the Spread Operator to Evaluate Arrays In-Place challenge. Thank you!

Here’s a link showing your solution in action using the pythontutor.com service you recommend above. Thank you for that recommendation!

1 Like

Here are my solutions for the next three algorithms:

Repeat a String Repeat a String

My first attempt looked like the following:

``````function repeatStringNumTimes(str, num) {
let returnStr = '';

for (let numCount=0; numCount < num; numCount++) {
if (num > 0) {
returnStr += str;
}
}

return returnStr;
}
``````

In thinking about it further and attempting to figure out a recursive way to accomplish this, I figured this out:

``````function repeatStringNumTimes(str, num) {
return num <= 0 ? "" : str + repeatStringNumTimes(str, num-1);
}
``````

The Repeat a String Repeat a String fCC guide shows a `while loop` solution, `recursive` solution, and a solution that uses the `repeat()` method, which the challenge says not to use. I think the `while loop` solution is more straightforward and easier to understand than my `for loop` solution above:

``````function repeatStringNumTimes(str, num) {
var accumulatedStr = '';

while (num > 0) {
accumulatedStr += str;
num--;
}

return accumulatedStr;
}
``````
Truncate a String

This was what I came up with:

``````function truncateString(str, num) {
return str.length > num ? `\${str.slice(0, num)}...` : str;
}
``````

Interestingly, I think the Truncate a String fCC guide makes it more complicated than it has to be, at least with the current test cases. For instance, `line 5` of the advanced code solution is:

`return str.slice(0, num > 3 ? num - 3 : num) + '...';`

If one uses the following instead, it’ll still pass all of the tests without the need to use another ternary operator:

`return str.slice(0, num) + '...';`

The advanced solution then becomes very similar to my solution above, except I use a template literal.

I may submit a suggested change to the guide entry if I get the time and energy.

Finders Keepers

My first attempt looked like this:

``````function findElement(arr, func) {
for (let num of arr) {
if (func(num)) return num;
}
}
``````

Then, I refactored using `filter()` to get this:

``````function findElement(arr, func) {
return arr.filter(item => func(item) ? item : undefined);
}
``````

That’s not too bad, a little awkward maybe. However, according to the Finders Keepers fCC Guide, there’s a much better way to do this using the `filter()` method:

``````function findElement(arr, func) {
filterArr = arr.filter(func);
return filterArr;
}
``````

Which can be refactored even further to:

``````function findElement(arr, func) {
return arr.filter(func);
}
``````

Any suggestions for improvement on the above solutions?

How’s everyone doing so far? I’ve noticed that the algorithms tend to take me longer to work on and figure out, especially if I take into account the research I do after I come up with a working solution in order to make that solution better. Anyone else experiencing this? 2 Likes

I got this for Finders Keepers

``````function findElement(arr, func) {
return arr.find(func);
}
``````

This was my first pass

``````function findElement(arr, func) {
for(let i = 0; i < arr.length; i++){
if(func(arr[i])){
return arr[i]
}
}
}
``````
1 Like

Thanks @camper!

I usually use ‘Live Programming Mode’ I think it’s better 