Categories
JavaScript Answers

How to Shuffle a JavaScript Array?

Shuffling a JavaScript array is something that we’ve to do sometimes.

In this article, we’ll look at how to shuffle a JavaScript array.

Swapping Array Entries Randomly

One way to shuffle a JavaScript array is to swap different array entries’ positions randomly.

For instance, we can write:

const shuffleArray = (array) => {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
}

const arr = [1, 2, 3]
shuffleArray(arr)
console.log(arr)

In the shuffleArray function, we loop through the array with the for a loop.

Then we pick a random index from the array with the Math.random method.

And then we do the swap after that by getting the entries and assigning them to the other item’s position.

array is changed in place.

So after calling shuffleArray on arr , we get an array with the items swapped in position.

This is called the Durstenfeld shuffle, which is an optimized version of the Fisher-Yates shuffle algorithm.

The sort Method and Math.random

We can use the sort method and Math.random together to shuffle an array.

For instance, we can write:

const arr = [1, 2, 3].sort(() => .5 - Math.random());
console.log(arr)

We return a random number between -0.5 and 0.5 in the callback to lets us shuffle the array.

This is because if the returned number is negative, then the position of 2 elements it’s iterating through stays the same.

Otherwise, they’re swapped.

However, this is biased and it’s also slow.

But this is the easiest way to shuffle an array with JavaScript.

Conclusion

There’re a few ways to shuffle an array with JavaScript.

They all needs the Math.random method to pick a random number.

Categories
JavaScript Answers

How to Check if an Object has a Specific Property in JavaScript?

JavaScript objects are created dynamically.

This means that we may not know what content is in a JavaScript object.

Therefore, we’ve to find ways to check if an object contains a specific property.

In this article, we’ll look at how to check if an object has a specific property in JavaScript.

The hasOwnProperty Method

The hasOwnProperty is a method that are inherited from the Object.prototype .

Most objects inherit from them unless we specify them not to be inherited from it.

Therefore, we can write:

const obj = {
  a: 1,
  b: 2,
  c: 3
}

console.log(obj.hasOwnProperty('a'))
console.log(obj.hasOwnProperty('d'))

to call hasOwnProperty with the property name string.

The first console log should log true since a is in obj .

The second console log should log false since d is not in obj .

The hasOwnProperty method is inherited from Object.prototype , so it can easily be overwritten by other pieces of code.

To avoid this issue, we can call hasOwnProperty with call by writing:

const obj = {
  a: 1,
  b: 2,
  c: 3
}

console.log(Object.prototype.hasOwnProperty.call(obj, 'a'))
console.log(Object.prototype.hasOwnProperty.call(obj, 'd'))

We call hasOwnProperty with Object.prototype.hasOwnProperty.call which can’t be overwritten like with the hasOwnProperty method.

The first argument is the value of this , which should be set to the object we’re checking the property for.

And the 2nd argument is the property name string itself, which is the first argument of hasOwnProperty when we call it the first way.

Therefore, we should get the same result as before.

The in Operator

The in operator lets us check for non-inherited and inherited properties.

It’ll return true if there’s an inherited or non-inherited property with the given property name.

For instance, if we have:

const obj = {
  a: 1,
  b: 2,
  c: 3
}

console.log('a' in obj)
console.log('hasOwnProperty' in obj)

Then they both log true since a is in obj itself.

And hasOwnProperty is inherited from Object.prototype .

Lodash has Method

We can also use the Lodash has method to check if a property is a non-inherited property of an object.

For instance, if we write:

const obj = {
  a: 1,
  b: 2,
  c: 3
}

console.log(_.has(obj, 'a'))
console.log(_.has(obj, 'hasOwnProperty'))

Then the first console log logs true .

And the 2nd console log logs false .

Conclusion

There’re many ways to check if a property is in an object.

We can also distinguish them between inherited and non-inherited properties.

Categories
JavaScript Answers

How to Detect an “Invalid Date” Date Instance in JavaScript?

If we’re trying to parse JavaScript dates, sometimes we may get ‘invalid date’ values.

If we try to parse invalid date values, then our JavaScript program may crash.

In this article, we’ll look at how to detect an ‘invalid date’ date instance with JavaScript.

instanceof and isNaN

We can combine the use of the instanceof operator and the isNaN function to check for invalid dates.

The instanceof operator lets us whether an object is created from the Date constructor.

And the isNaN function lets us check whether the object converts to a timestamp when we try to cast it to a number.

isNaN tries to cast an object to a number before checking if it’s a number.

For example, we can write:

const isValidDate = (d) => {
  return d instanceof Date && !isNaN(d);
}

const validDate = new Date(2021, 1, 1)
const invalidDate = new Date('abc')
console.log(isValidDate(validDate))
console.log(isValidDate(invalidDate))

to create the isValidDate function which returns the expression d instanceof Date && !isNaN(d); to do both checks.

Then we can call it with validDate and invalidDate , which are valid and invalid date objects respectively.

Date.parse

We can also use the Date.parse method to try to parse a Date instance into a date.

For instance, we can write:

const validDate = new Date(2021, 1, 1)
const invalidDate = new Date('abc')
console.log(!isNaN(Date.parse(validDate)))
console.log(!isNaN(Date.parse(invalidDate)))

Date.parse returns a UNIX timestamp if it’s a valid date.

So if we pass in validDate to Date.parse , we should get an integer timestamp returned.

And if we pass in invalidDate , we should get NaN returned.

This means we can use isNaN again to check whether the result returned by Date.parse is a number.

instanceof and isFinite

We can call isFinite instead of isNaN in our valid date check.

This is because isFinite only returns true if anything that can be converted to a finite number is passed in as an argument.

To use it, we write:

const isValidDate = (d) => {
  return d instanceof Date && isFinite(d);
}
const validDate = new Date(2021, 1, 1)
const invalidDate = new Date('abc')
console.log(isValidDate(validDate))
console.log(isValidDate(invalidDate))

This way, we can get rid of the negation before isNaN , which makes the isValidDate function easier to read.

Conclusion

We can check for valid date objects with the instanceof operator, isNaN , isFinite , or Date.parse .

Categories
JavaScript Answers

How to Loop Through a Plain JavaScript Object?

JavaScript objects are dynamically created by adding properties to them.

Therefore, we may have to loop through its properties with a loop to get the values.

In this article, we’ll look at how to loop through a plain JavaScript object.

Object.keys

The Object.keys method returns an array of all non-inherited string property keys of an object.

To use it, we can write:

const obj = {
  a: 1,
  b: 2,
  c: 3
}
for (const key of Object.keys(obj)) {
  console.log(key, obj[key])
}

We use the for-of loop to loop through the array of keys returned by Object.keys .

Then we can access the value by passing the key into the square brackets after obj .

So we see:

a 1
b 2
c 3

logged.

Object.values

We can just loop through the values of an object with the Object.values method.

For instance, we can write:

const obj = {
  a: 1,
  b: 2,
  c: 3
}

for (const value of Object.values(obj)) {
  console.log(value)
}

Object.values return an array with all the properties values of an object, so we can use the for-of loop to log the property values.

And so we get:

1
2
3

in the console.

Object.entries

Also, we can use the Object.entries method to return an array with arrays of key-value pairs.

To do this, we can write:

const obj = {
  a: 1,
  b: 2,
  c: 3
}
for (const [key, value] of Object.entries(obj)) {
  console.log(key, value)
}

We destructure the key and value from each array entries returned by Object.entries .

Then we can log them in the loop body.

And we get the same result as we did in the previous example.

Loop Through Nested Objects

To loop through a nested object, we can create a function that calls itself to loop through their properties at each level of the object.

To do this, we write:

const obj = {
  a: 1,
  b: 2,
  c: {
    d: {
      e: 4
    },
    f: 5
  }
}
const loopNestedObj = obj => {
  for (const [key, value] of Object.entries(obj)) {
    console.log(key, value)
    if (typeof value === 'object' && value !== null) {
      loopNestedObj(value)
    }
  }
}

loopNestedObj(obj)

We create the loopNestedObj function that takes an obj object.

Inside the function, we have the same loop as in the previous example.

But we have an if block to check the value ‘s data type to see if it’s an object.

If it is, then we call loopNestedObj to loop through its content.

The expression typeof value === ‘object’ && value !== null is needed to check if value is an object since typeof null is also 'object' .

Therefore, we need both checks to check for an object.

Conclusion

We can traverse an object with the for-of loop and various static object methods provided by JavaScript.

Categories
JavaScript Answers

How to Listen to Events on Dynamically Created Elements with JavaScript?

Many items in a web page are dynamically created with JavaScript.

This means that we’ve to listen to events that are emitted by them so that we can use them to do something other than display content statically.

In this article, we’ll look at how to listen to events on elements that are created dynamically with JavaScript.

Event Delegation

We can listen to events emitted on the container element that has the dynamically created elements.

In the event listener, we can check which item is emitting an event do the stuff we want depending on the element emitting the event.

This is possible because events emitted by an element bubble up to its parent and ancestor elements all the way to the body and html elements unless we stop it manually.

Therefore, the body element’s event listener will pick up events from all its descendant elements if we allow them to propagate.

For instance, we can write the following HTML:

<div>

</div>

And create then write the following JavaScript to listen to click events emitted by the dynamically created p elements:

const div = document.querySelector('div')
for (let i = 1; i <= 100; i++) {
  const p = document.createElement('p')
  p.className = i % 2 === 1 ? 'odd' : 'even'
  p.textContent = 'hello'
  div.appendChild(p)
}

document.addEventListener('click', (e) => {
  if (e.target.className.includes('odd')) {
    console.log('odd element clicked', e.target.textContent)
  } else if (e.target.className.includes('even')) {
    console.log('even element clicked', e.target.textContent)
  }
});

In the code above, we get the div element with document.querySelector .

Then we use a for loop to add p elements inside the div 100 times.

We set the className of the element to set the value of the class attribute.

textContent has the value of the content of the p element.

Then we call appendChild on the div to add the p element inside the div.

Then to listen to click events on the p elements we just added, we listen to the click of document , which is the body element.

We call addEventListener to add the click listener to the body element.

Then we pass in a callback as the 2nd argument of addEventListener .

The e parameter is the event object.

It has information about the original element that emitted the event.

We get the element that originally emitted the event with the e.target property.

So we can get the value of the class attribute of the element with the e.target.className property.

And we get the value of the textContent property with the e.target.textContent property.

Conclusion

We can listen to events emitted by dynamically created HTML elements with event delegation.

We just listen to events from the ancestor of the elements that emit the events and then check which element emitted the event in the callback.