FAQ: Iterators - Review

Thanks. Everything is working fine now.

 /*----find index of 'Smith' in initial Array----*/
function index() {
  let count =0;
  for(let i=0; i<persons.length; i++){
    for(let y=0; y<findPerson.length; y++){      
      if(persons[i] == findPerson[y]){
        count++;
        console.log(`Match found: ${persons[i]}. Index: ${i}.`);     
      }            
    }    
  }
 return (`Current number of matches: ${count}`); 
}; 

console.log(index());

Prints:

Match found: Agent Smith. Index: 4.
Match found: Samantha Smith. Index: 5.
Current number of matches: 2

1 Like

This is how I did it. Using the .map() and the .join() method to remove the , commas from console.log. See code solution below.

const myArray = [‘Albany’,‘britain’,‘dubai’,‘ukraine’,‘luxembourg’]

const myName = myArray.map(word => {

return word[0];

});

console.log(myName.join(‘’));

Output:
Abdul

Hi there. You should make use of the .map() method instead of reduce(). The map() returns an array of the same size(same number of elements) as the input array, but only the char at the first index of each string element is returned into the ordj array (as shown below)
const ail = [‘you’, ‘orléans’, ‘uganda’]

const ordi = ail.map(word => {
return word[0];
});

The .join() is used on the ordi array to remove the , (commas) that the console.log would otherwise print. Thus giving us the output “you” which is interpolated and appended to the rest of string which is "I love " . Hope this helps.

console.log(I love ${ordi.join('')});

Output:
I love you

P.S for some reason the backticks for the template literal isn’t showing with the console.log(love you) line;

Hi all,

I’m trying to see if I can do something for the third “challenge”

Use the optional arguments in an iterator to include the index or the entire array. (Check out MDN’s Array iteration methods page for more information)

So I looked up MDN and note that the iterators, including .forEach(), accept index of the current element, and the array .forEach() was called upon as optional parameters in the callback function. So, I tried:

const animals = ['dog', 'parrot', 'cat', 'guinea pig', 'cut-off',
'donkey', 'horse', 'crocodile', 'monkey'];

const newArray = animals.forEach( (element, i, arr) => { 

    if (element === 'cut-off') console.log(arr[i]);
} );

And it works. However my question is why would we want to use index and/or the array passed as arguments at all? As the above is equivalent to

const newArray = animals.forEach( (element, i, arr) => { 

    if (element === 'cut-off') console.log(element);
} );

Can someone give an example of when these optional parameters can be useful?

To start with, what is the first thing we learn about .forEach()? Stumped? Okay, the first thing we learn is that .forEach() has no return value so assigning it is pointless since it will just be, undefined.

Now, as the callback parameters go, the element, what I call x is just that, the current element of the array. .forEach() is breakless so will iterate the entire array from left to right, by element. i is the index of the current element in the iteration. We can use this to enumerate an array:

const arr = ['zero', 'one', 'two', 'three', 'four', 'five']
const obj = {}
arr.forEach((x, i) => obj[i] = x)
console.log(obj)
{
    "0": "zero",
    "1": "one",
    "2": "two",
    "3": "three",
    "4": "four",
    "5": "five",
    "i": "five"
}

That last value is an unexplained artefact that will take some research to discover why it is there at all. Obviously this needs to be thought out more. You get the idea, though.

Let’s see if we can enumerate the array itself:

arr.forEach((x, i, a) => a[i] = [i, x])
console.log(arr)
[
  [0, 'zero'],
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
  [4, 'four'],
  [5, 'five']
]

Now we can see where that third optional parameter fits in. It is the array, itself which allows us to work directly on it within the callback.

1 Like

I will have to re-read your example a couple of times, but thanks for reminding about return value of .eachOf(). I was just looking for an easy example with the extra parameters so assigned it to variable without thinking, or maybe I had something else there before, don’t remember!

1 Like

I am feeling particularly stupid today. I have gotten this far with relatively few problems.

But literally don’t understand what is being asked for in the below challenge from the review:

Use the optional arguments in an iterator to include the index or the entire array.

If anyone can enlighten me I would be eternally grateful.

Which iterator callback function has optional parameters?

Thank you for helping me focus on this.

I’ve re-read the documentation (several times!) and finally spotted that the reduce() iterator has an optional initialValue.

Makes more sense to me now thanks to your prompt :slight_smile:

1 Like

Also look into .forEach() We’ve posted some examples recently on the optional parameters. Should come up in a quick search of the forums.

.forEach @mtf

will bring up some of it.

1 Like

Hello all. Quick question regarding :

  • Use .reduce() to take a multi-layered array and return a single layer array from scratch.

Is the below solution acceptable using concat?

const fatArray = [[1,2], [3,4], [5,6]];

console.log(fatArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue)))
;

In the above setting using a two dimension array the output is a single dimension array, so yes, the solution is acceptable.

Given that the default starting (initial accumulator) value is an empty list, implicitly, we can be more explicit by specifying it as such, for greater clarity, but this is a moot point.

const flattened = fatArray.reduce((a, b) => a.concat(b), [])

console.log(flattened)  // [1, 2, 3, 4, 5, 6]
1 Like

I tried the " * Use .reduce() to take a multi-layered array and return a single layer array from scratch." challenge with an initial array that can be a mixed of single value, string, and nested array, came up with that :

const layerArray = [4,[5,6],[7,8],9,'test'];
const single = layerArray.reduce((acc,init) =>{
  if( Array.isArray(init) ){
    init.forEach(item => acc.push(item));
  }else{
    acc.push(init);
  }
  return acc;
},[]);
 console.log(single);
//it logged [ 4, 5, 6, 7, 8, 9, 'test' ]