DEV Community

Cover image for JavaScript30: Day 4 - Solve Real Life challenges using Array Methods
Anik Khan
Anik Khan

Posted on

JavaScript30: Day 4 - Solve Real Life challenges using Array Methods

I've completed the Day 4 of Wes Bos JavaScript 30.
Unlike the previous challenges, this one is solely focused on language features, no HTML/CSS. It's about using various array methods to manipulate data.

What did I solve?

Wes Bos posed some of the very interesting and real-life problems which can be solved by various array methods i.e. Array.prototype.filter(), Array.prototype.map(), Array.prototype.sort(), Array.prototype.reduce()

My Experience

To be honest, this part made me feel at home😊 Being someone who had spent more time in the backend, it comes off as less intimidating than the CSS.
Having said that, I struggled with a couple of challenges especially the last one.

The Challenge & My Learnings

Given Data:


    const inventors = [
      { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
      { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
      { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
      { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
      { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
      { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
      { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
      { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
      { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
      { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
      { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
      { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
    ];
Enter fullscreen mode Exit fullscreen mode
  • Filter the list of inventors for those who were born in the 1500's
const earlyInventors = inventors.filter((inventor) => inventor.year >= 1500 && inventor.year < 1600)
console.table(earlyInventors)
Enter fullscreen mode Exit fullscreen mode

The filter() method- goes through each array element, check them against a certain condition, returns a new array with the elements that met the condition.

  • Give us an array of the inventors first and last names
const inventorsName = inventors.map((inventor) => `${inventor.first} ${inventor.last}`)
 console.table(inventorsName)
Enter fullscreen mode Exit fullscreen mode

The map() method- goes through each element, make them do a specific task, and returns a new array with the result.
Here, each inventor from the inventors array is passed to an arrow function that concatenates the first name and last names & returns an array with the results

  • How many years did all the inventors live all together?
const livingYear = inventors.reduce((acc, inventor) => acc + (inventor.passed - inventor.year), 0)
console.log(livingYear)
Enter fullscreen mode Exit fullscreen mode

The reduce() method- executes a reducer function (that you provide) on each element of the array, resulting in a single output value.
When you asked to accumulate something from an array, you probably wanna use reduce() method.
The reducer function that it executes can take up to 4 arguments; but commonly we use 2 arguments- accumulator and the current value.
The accumulator is the accumulated value previously returned in the last invocation & we usually initially initialize it to 0 (as the second argument of reduce() method).
And the current value is the current item being processed.

  • Sort the inventors by years lived
const byLivingYears = inventors.sort((a, b) => {
      return (a.passed - a.year) < (b.passed - b.year) ? 1 : -1
    })
    console.table(byLivingYears)
Enter fullscreen mode Exit fullscreen mode

The sort() method- when provided with a compare function(which takes 2 arguments) like here, all non-undefined array elements are sorted according to the return value of the compare function.
Return value -1 means, item comes first
Return value 1 means, item comes last
Return value 0 means, the item's position is unchanged
For example, aNumber < anotherNumber ? -1 : 1
means aNumber will comes first if it less than the anotherNumber & vice versa.

//select all the boulevards anchors form the page
    //#mw-content-text is found by inspection chrome dev tool
    const linksNode = document.querySelectorAll('#mw-content-text a')
    //convert the linksNode to array, find the text of the anchor tag & get all that includes 'de' in them
    const deBoulevard = [...linksNode].map(link => link.textContent).filter(boulevards => boulevards.includes('de'))
    console.table(deBoulevard)
Enter fullscreen mode Exit fullscreen mode

To solve this we need to use multiple array methods as you can see.
First, we select the DOM element that contains all the anchor tags, using the mw-content-text id
As querySelectorAll() returns a nodeList we need to convert that to an array & then we used map() to find the text of the anchortags and then used filter() to filter by checking if they include 'de'

Now working with different data-

    const people = ['Beck, Glenn', 'Becker, Carl', 'Beckett, Samuel', 'Beddoes, Mick', 'Beecher, Henry',
      'Beethoven, Ludwig', 'Begin, Menachem', 'Belloc, Hilaire', 'Bellow, Saul', 'Benchley, Robert',
      'Benenson, Peter', 'Ben-Gurion, David', 'Benjamin, Walter', 'Benn, Tony', 'Bennington, Chester',
      'Benson, Leana', 'Bent, Silas', 'Bentsen, Lloyd', 'Berger, Ric', 'Bergman, Ingmar', 'Berio, Luciano',
      'Berle, Milton', 'Berlin, Irving', 'Berne, Eric', 'Bernhard, Sandra', 'Berra, Yogi', 'Berry, Halle',
      'Berry, Wendell', 'Bethea, Erin', 'Bevan, Aneurin', 'Bevel, Ken', 'Biden, Joseph', 'Bierce, Ambrose',
      'Biko, Steve', 'Billings, Josh', 'Biondo, Frank', 'Birrell, Augustine', 'Black, Elk', 'Blair, Robert',
      'Blair, Tony', 'Blake, William'
    ];
Enter fullscreen mode Exit fullscreen mode

See all elements are string containing last and first name. They aren't structured correctly to work with. So if we need to do some operation on them we need to give them some shape based off of our challenge.

  • Sort the people alphabetically by last name

Sort the people alphabetically wouldn't be hard but as the first name and last name are packed in one single string, we need to find a way to split them. and do the operation accordingly.

    const peopleByLastName = people.sort((a, b) => {
      //The split() method divides a String into an ordered list of substrings
      const [aLast, aFirst] = a.split(',')
      //const [aLast, aFirst] is called restructuring 
      //which makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
      const [bLast, bFirst] = b.split(',')
      return aLast > bLast ? 1 : -1 //in ascending order. smaller letter like 'a' comes first
    })
    console.log(peopleByLastName)

Enter fullscreen mode Exit fullscreen mode
  • Sum up the frequency of each of these-
 const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car',
      'truck'
    ];
Enter fullscreen mode Exit fullscreen mode

This one is a bit tricky for me to solve. But the idea was pretty simple. The concept is each array item will be the object's key and its number of appearances will be it's key. For example, {car: 5, truck: 2}

  1. create an empty object
  2. loop through each array item; when a new item is found assigned it's value to 1 and if the item is existed previously increase it's value.
   const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car',
      'truck'
    ];
    const vehicle = data.reduce(function (obj, item) {
      if (!obj.item) { //checks if the item is new
        obj.item = 0 //assign 0 for the new item
      }
      obj.item++ //icrement the value
      return obj
    }, {})
Enter fullscreen mode Exit fullscreen mode

GitHub:

View on GitHub

Top comments (2)

Collapse
 
pentacular profile image
pentacular • Edited

I think this has a typo

 if (!obj.item) { //checks if the item is new

and should be generally obj[item].

But it might be a bit nicer like this:

const histogram = (map, key) => map.set(key, (map.get(key) || 0) + 1);

data.reduce(histogram, new Map())
Collapse
 
akdeberg profile image
Anik Khan • Edited

Hey many many thanks for the suggestion.😊 I hope many would find this helpful 💗