FAQ: Code Challenges: Intermediate JavaScript - justCoolStuff()

This comment I am writing is not a question it is a suggestion to the creators of the content.
This section and the curriculum within is presented as “practice”. However, I disagree that it is “Practice”. It is new curriculum that hasn’t been discussed in previous chapters as there are new uses and formatting and arrangement of syntax. At some point, I realized enough to stop bothering to try to come up with a solution of my own, which would never have arrived at anyways, as I am unfamiliar with these new and subtle syntax behaviors which are wonderful and important to know how to utilize, but can’t possibly be arrived at through a logical approach by anyone who isn’t already familiar with them. ie. using multiple arguments in an arrow function. Thought you should know, this reminds me more of what irritated with all of teamtreehouse’s curriculum and made me change to codeacademy to begin with. Maybe, have some lessons on this first before the practice or else people will give up and quit…I had little issues with completing your JavaScript track and successfully did so!

Thanks.

I Want to know in this code what’s mean ‘item’ in this function can someone answer me

Item refers to whatever is passed into the “isInSecondArray” function.

Has anyone tried to use the .forEach() method? I was able to solve the problem using a for loop, but I want to understand where I am messing up with my .forEach() strategy.

I’ve left my for loop approach as reference.

function justCoolStuff (arr1, arr2) {
  let newArr = [];

 /* newArr = arr1.filter((e1) => {
    for (i=0; i<arr2.length; i++){
        if(e1 === arr2[i]){
          return true;
        }
      }
    })*/

  newArr = arr1.filter((e1) => {
    arr2.forEach((e2)=>{
      if(e1 === e2){
          return true;
          }
        })
        
      }
    )

  return newArr;
}

We generally want to minimize the amount of logic in a .filter() callback function. Truth is we have a companion iterator to handle that part of the logic, .includes(). It too is a predicate function that returns a boolean.

 a.filter(x => b.includes(x))

For all practical purposes .forEach() is not aptly suited to a filter since it returns undefined.

1 Like

Thanks for your response! I’m still wrapping my head around the different tools that JS offers. I totally get how .includes is a better method.

For purpose of understanding, is there a way to have .forEach() return something other than undefined?

1 Like

No, not really. However we can build an array (or object) that will be the outcome, not the return.

const list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
const arr = []
list.forEach(function (x, i) {
  this.push([i, x])
  }, arr)
console.log(arr)
[ [ 0, 1 ],
  [ 1, 2 ],
  [ 2, 3 ],
  [ 3, 4 ],
  [ 4, 5 ],
  [ 5, 6 ],
  [ 6, 7 ],
  [ 7, 8 ],
  [ 8, 9 ] ]

We’ve effectively enumerated the list array. Here is a similar array of objects…

const list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
const arr = []
list.forEach(function (x, i) {
  const temp = {}
  temp[`${i}`] = x
  this.push(temp)
  }, arr)
console.log(arr)
[ { '0': 1 },
  { '1': 2 },
  { '2': 3 },
  { '3': 4 },
  { '4': 5 },
  { '5': 6 },
  { '6': 7 },
  { '7': 8 },
  { '8': 9 } ]

Awesome! Thanks for the help :slight_smile:

1 Like

Hello!

I wonder why it won’t let me pass the test with this code…

function justCoolStuff(arr1, arr2) {

  let newArr = [];

  for(let i=0; i<arr2.length; i++){
      arr1.filter(function checkWords(word){
          if(word === arr2[i]) {
             newArr.push(word);
          }
      });
  }

return newArr;
}

It does return what needs to be returned, but it won’t let me pass the test.
Anyone who could clarify this for me?

Thanks!

The Array.filter() method is an iterator that takes a predicate function for an argument. That function returns a boolean. The filter returns an array of values from the context list that satisfy the predicate function (return true). We assign the output to a new variable.

const word = "JavaScript"

const predicate = x => x === word

const newArr = oldArr.filter(predicate)

Your function above is behaving like the Array.forEach() method.

What other method in the iterator category also returns a boolean? How might we pair it up with .filter() to compare two arrays?

I would like to know why this code return undefined, what I missed? How can I correct it? Thanks.

const justCoolStuff = (arr1, arr2) => {
  arr1.filter(word => {
    for(i = 0; i <= arr2.length; i++){
          if(arr1 === word[i]){
          return true;
      }
    }
  })
}

const coolStuff = ['gameboys', 'skateboards', 'backwards hats', 'fruit-by-the-foot', 'pogs', 'my room', 'temporary tattoos'];

const myStuff = [ 'rules', 'fruit-by-the-foot', 'wedgies', 'sweaters', 'skateboards', 'family-night', 'my room', 'braces', 'the information superhighway']; 

console.log(justCoolStuff(myStuff, coolStuff))

The return in your code is inside the filter callback function. The array that filter returns needs to be returned to complete the overall process.

Don’t forget to declare your iteration variable with, let i = 0, else that variable will pollute the global scope.

There is a simpler method than what you have used as a callback. Can you think of which iterator will satisfy this in a similar way?

1 Like

The return in your code is inside the filter callback function. The array that filter returns needs to be returned to complete the overall process.

I get it, thanks so much for your help.

There is a simpler method than what you have used as a callback. Can you think of which iterator will satisfy this in a similar way?

Yes, I noted that the .includes() works like a charm. :blush:

1 Like

I don’t understand the return portion of the function. Specifically, what’s going on within .filter() method?

Why is there a second arrow within the .filter() method?

That is a function, the callback which is run on every value in the context array.

context.filter(callback)

We use arrow syntax for conciseness.

x => x > 0

The above is a predicate function since it returns the evaluation of the comparison expression, a boolean.

const arr = [4, -12, 11, -3, 9, 17, -22, -19, 8]
const pos = arr.filter(x => x > 0)
console.log(pos)    //  [4, 11, 9, 17, 8]

See how we filtered out all the positive numbers?

In ES5 vanilla JS the code would look like this…

var pos = arr.filter(function (x) {
    return x > 0;
})

which is still valid code, albeit more verbose.

Is this helping any?

1 Like

Your explanation of what’s going on in the filter() method makes sense however, I’m still confused on when I should use the second arrow. Are there specific scenarios for when/when not to use the second arrow?

1 Like

It is not really a second arrow as much as a second function.

const justCoolStuff = (arr1, arr2) => {
  return ...
};

That is the outer function expression (indicated by the parameter list and the arrow).

The return statement includes another expression, the .filter() method which itself, as we have described takes a function, a predicate function. All the iterator is looking for is a boolean on return from each call it makes to that function as it iterates the array.

const justCoolStuff = (arr1, arr2) => {
  return arr1.filter(item => arr2.includes(item));
  //                 ---- predicate function ---
};
1 Like

Ok this makes more sense. Thank you for your help!

1 Like