Data Structures and Modern Operators

Data Structures and Modern Operators

There are 4 data structures that are in-built in JavaScript. We will cover all 4 data structures in depth. Even there are non-built-in data structures. But those data structures are not within the scope of this blog.

If you are a beginner in JavaScript do check out our in-depth JavaScript series JavaScript Series.

We will mostly focus on practical learning instead of theoretical learning. We will include only the required theory for the practical.

Destructuring Arrays

The destructuring in JavaScript makes it possible to unpack arrays into distinct variables.

Frame 37 (2).png

While destructuring we use the same type of brace on both sides. if you take a look at the above image we destructured an array in 3 variables called a,b, and c. After b we have left blank space which will skip that term. Let's try to understand with an example.

let [a,,b,c] = [1,2,3,4]; // a=1 , b=3 , c=4
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3

Now with the help of destructuring, we can swap 2 variables' values.If we have x=1 and y=2 after swaping it becomes x=2 and y=1.

let x= 1;
let y = 2;
console.log("Before Swap");
console.log(`x : ${x}`); // 1
console.log(`y : ${y}`); // 2
[x,y] = [y,x];
console.log("After Swap");
console.log(`x : ${x}`); // 2
console.log(`y : ${y}`); // 1

Destructuring Objects

Destructuring objects is similar to arrays but there are a few changes we need to do. We have to mention the same name of the key mentioned in an object. We can change the name but it needs some changes. we will try to understand both approaches with help of examples.

Without changing the name mentioned in the object

let obj = {
fname: "JavaScript",
age: 25,
}

let {fname,age} = obj;
console.log(fname); // JavaScript
console.log(age); // 25

changing name mentioned in object

let obj = {
fname: "JavaScript",
age: 25,
}

let {fname: alpha,age: beta} = obj;
console.log(alpha); // JavaScript
console.log(beta); // 25

We can also give default values while destructuring object. They are useful when there is no matching property of object.

let obj = {
fname: "JavaScript",
}

let {fname: alpha,age: beta=0,year=0} = obj;
console.log(alpha); // JavaScript
console.log(beta); // 0
console.log(year); // 0

From the above example, we can see that there was no age and year value, but we gave default values to age and year it printed those default values.

Nested Destructuring

Suppose there is an object which has one more object in it. How will you destructure that object. It's simple we can do nested destructuring. Refer below example.

let obj = {
  Jan: {
        opening: 10,
        closing: 7, 
  }
}

  let {Jan: {opening,closing}} = obj;
  console.log(opening); // 10
  console.log(closing); // 7

Spread Operator

Spread syntax (...) allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected.

Let's understand it by example.

let arr = [1,2,3,4,5];
let arr2 = [...arr,6,7,8,9,10]; 
let arr3 = [arr,6,7,8,9,10];
console.log(arr); // [1,2,3,4,5]
console.log(arr2); // [1,2,3,4,5,6,7,8,9,10]
console.log(arr3); // [[1,2,3,4,5],6,7,8,9,10]

In the above example, arr is copied and pasted in arr2 element by element. But if we directly mentioned arr in arr2 it would be a nested array instead of the array.

Rest Operator

The rest operator is the same as spread operator. But when we use (...) on the left-hand side of assignment operator(=) it is the rest operator and when we use (...) on the right and side of assignment operator(=) it is spread operator. Let's understand with an example.

// ARRAY EXAMPLE
let arr = [1,2,3,4,5];
let arr2 = [...arr,6,7,8,9,10]; // spread operator

let [a,...rest] = [1,2,3,4,5];  // rest operator
let [c,...d] = [...arr,...arr2] // rest and spread operator together

We can use the rest operator at last only to catch remaining element of array or object

// OBJECT EXAMPLE
let obj = {
  fname: "JavaScript",
  year: 1995,
  age: 25,
}

let {fname,...rest} = obj;
console.log(fname); // fname: "JavaScript"
console.log(rest); // year: 1995, age: 25

Remember the key name should be the same or we need to change syntax. We learned this in the above section.

Enhanced Object Literals

In ES6, there are some advanced object literals introduced to make working with objects easier.

  • Before ES6 when we wanted to copy one object into another object, we have to give a key: value pair. But in ES6 we just have to give a variable name. It's better to understand with examples.
// BEFORE ES6
let obj = {
    fname: "JavaScript",
    age: 25,
}
let obj2 = {
    year: 1995,
    obj:obj,
}
console.log(obj2);

// AFTER ES6
let obj = {
    fname: "JavaScript",
    age: 25,
}
let obj2 = {
    year: 1995,
    obj,   // We just have variable name
}
  • We used to write function in object with key: value pair, instead of value we use to write function. But new way to write function in object was introduced. We just have to write function name and braces. Refer below example to understand better.
// BEFORE ES6
let obj = {
    fname: "JavaScript",
    age: 25,
    details: function(){
        console.log(`Age of ${this.fname} is ${this.age} years.`)
    },
}
obj.details();

// AFTER ES6
let obj = {
    fname: "JavaScript",
    age: 25,
    details(){
        console.log(`Age of ${this.fname} is ${this.age} years.`)
    },
}
obj.details();
  • We had to write key names before ES6, but after ES6 we can take array values directly as a key name in an object. Refer to the below example to understand better.
// BEFORE ES6
let obj = {
    Mon: "Monday",
    Tue: "Tuesday",
    Wed: "Wednesday",
}
console.log(obj);

// AFTER ES6
let arr = ["Mon","Tue","Wed"];
let obj = {
    [arr[0]]: "Monday",
    [arr[1]]: "Tuesday",
    [arr[2]]: "Wednesday",
}
console.log(obj);

Optional Chaining

The optional chaining operator (?.) enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid. Let's take an example to understand it better.

let obj = {
  fri:{
        open:12,
        close:11,
    },
    sat:{
        open:1,
        close:9,
    },
    sun:{
        open:7,
        close:3,
    },
    greet(){
        console.log("Morning");
    }
};

// without chaining the operator
if(obj.mon.open){
  console.log(obj.mon.open);
}
else{
  console.log("Does not exists");
}

// with chaining the operator
let exp = obj.mon?.open;
console.log(exp);

let exp = obj.fri?.open;
console.log(exp);

Now in the above example, if everything before optional chaining (?.) exists then only it will print, or else it will give undefined.

optional chaining with array

let days = ["mon","tue","wed",'thu',"fri","sat","sun"];
for(let day of days){
    console.log(openingHours[day]?.open || "closed");
}

optional chaining on methods

let obj = {
  fri:{
        open:12,
        close:11,
    },
    sat:{
        open:1,
        close:9,
    },
    sun:{
        open:7,
        close:3,
    },
    greet(){
        console.log("Morning");
    }
};
obj.loops?.() || console.log("does not exists");
obj.greet?.() || console.log("does not exists");

Looping objects

Objects are not iterable still we can loop them in an indirect way. There is an inbuild object method we can use to loop through objects.

const obj= {
    fri:{
        open:12,
        close:11,
    },
    sat:{
        open:1,
        close:9,
    },
    sun:{
        open:7,
        close:3,
    },
}

// For keys
for(const day of Object.keys(obj)){
    console.log(day);
}

// For values
for(const day of Object.values(obj)){
    console.log(day);
}

// For keys and values
for(const [key,{open,close}] of Object.entries(obj)){
    console.log(key + " " +open + " " +close);
}

Sets

The set is a collection of unique elements. There is no duplication in a set. We can pass iterable to set. The most common iterable passed to a set is an array. Let's try it using an example.

let arr = [1,2,3,3,4,4,5,5];
let set = new Set(arr);
console.log(set);  //print only unique values 1,2,3,4,5

size property

It returns size of set.

let arr = [1,2,3,3,4,4,5,5];
let set = new Set(arr.size);
console.log(set);  // 5

has property

It return true if set contain value given by user. It is similar to includes property of array.

let arr = [1,2,3,3,4,4,5,5];
let set = new Set(arr);
console.log(set.has(5));  // true
console.log(set.has(1001));  // false

add property

We can add a new value to the set using add. If the value we are adding already exists in the set it won't add. But the value we passed doesn't exist it will add at end of a set.

let arr = [1,2,3,3,4,4,5,5];
let set = new Set(arr);
console.log(set); //1,2,3,4,5
set.add(5);
console.log(set); //1,2,3,4,5
set.add(6);
console.log(set); //1,2,3,4,5,6

looping through set

It is very easy to loop through set. We just have to use for loop like any other data structure.

let arr = [1,2,3,3,4,4,5,5];
let set = new Set(arr);
for(let key of set){
  console.log(key); 
}
// OUTPUT :
// 1
// 2
// 3
// 4
// 5

Maps

The map is a data structure that helps in storing the data in the form of pairs. The pair consists of a unique key and a value mapped to the key. It helps prevent duplicity.

A Map is ordered and iterable, whereas an object is not an ordered and not an iterable property.

We have to use set property to push elements into map. We can use any data type as key in maps.

let map = new Map();
map.set("name": "JavaScript");
console.log(map);  // name => JavaScript
map.set(2: 1995);
console.log(map);  // name => JavaScript , 2 => 1995

get property

We can pass key name to get value of that key using get property.

let map = new Map();
map.set("name": "JavaScript");
console.log(map.get("name")); // JavaScript

has property

It returns a Boolean value. It checks if a key is present given by the user and then returns true or else false.

let map = new Map();
map.set("name": "JavaScript");
console.log(map.has("name")); // true
console.log(map.has("age")); // false

size property

It returns count of pair of key,value present in map.

let arr = [1,2,3,3,4,4,5,5];
let set = new Set(arr);
set.add(5);
set.add(6);
console.log(map.size); // 6

object to map

We can convert object to map. But for that we need to get key and value pair from objects which can be done using Object.entries().

let obj = {
    name: "JavaScript",
    age: 25, 
    1: 2006,
    5: 2008,
}
let mp = new Map(Object.entries(obj));
console.log(mp); // name => JavaScript, age => 25, 1 => 2006 , 5 => 2008

Iterate through map

We can use for of loop to iterate through map.

let obj = {
    name: "JavaScript",
    age: 25, 
    1: 2006,
    5: 2008,
}
let mp = new Map(Object.entries(obj));

// iterate through map
for(const [key,value] of mp){
    console.log(`${key} : ${value}`);
}

When to use which data structure

There are two types of data structure. There are different use cases for different data structures.

  • Simple list
  • key-value pair

Frame 38 (1).png

  • There are other non-built-in data structures as well we will not discuss them here. *

When to use an Array

  • Use when you need to order a list of values (may contain duplicates).
  • Use when you need to manipulate data.

When to use Set

  • Use it when you need to work with unique values.
  • Use when high-performance is really important.
  • Use to remove duplicates from arrays.

When to use Object

  • More “traditional” key/value pair.
  • Use when you need to include functions (methods).
  • Use when working with JSON (can convert to map).

When to use Map

  • Better performance.
  • Keys can have any data type.
  • Easy to iterate.
  • Easy to compute size.
  • Use when you simply need to map the key to values.
  • Use when you need keys that are not strings.

Hope you understood everything. Please do leave your valuable feedback.

If you are a beginner in JavaScript please Check out my new JavaScript series to learn new things about JavaScript. JavaScript Series

Did you find this article valuable?

Support Kedar Makode by becoming a sponsor. Any amount is appreciated!