8
Author: Vivek Bisht
Translator: Frontend Xiaozhi
Source: blog
Mobile reading: https://mp.weixin.qq.com/s/nbYsKonWtLNK95jMd4dY-A

If you have dreams and dry goods, search on for 160e3960016b48 [Daily Move to the World] Follow this brush-bowl wisdom who is still doing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line interview complete test site, information and my series of articles.

In programming, if you want to go deeper, data structure is a piece we must understand. The motivation for learning/understanding data structure may be different. On the one hand, it may be for interviews, on the other hand, it may be just to improve your skills. Or the project needs. No matter what the motivation is, if you don’t know what array structure is and when to use application words, then learning data structure is a tedious and boring process 😵

This article discusses when to use them. In this article, we will learn about arrays and objects. We will try to understand when to choose a data structure Big O notation

Big O notation big zero symbol is generally used to describe the complexity of the algorithm, such as the execution time or the space occupied by the memory (disk), especially the worst case.

Array

array is one of the most widely used data structures. The data in the array is structured in an orderly manner, that is, the first element in the array is stored in index 0 , the second element is stored in index 1 , and so on. JavaScript provides us with some built-in data structures, array is one of them👌

In JavaScript, the simplest way to define an array is:

let arr = []

The above line of code creates a dynamic array (with unknown length). In order to understand how to store the elements of the array in memory, let's look at an example:

let arr = ['John', 'Lily', 'William', 'Cindy']

In the above example, we create an array containing some people's names. The name in the memory is stored as follows:

clipboard.png

In order to understand how arrays work, we need to perform a few operations:

Add elements:

In JavaScript arrays, we have different ways to add elements at the end of the array, switches, and specific indexes.

adds an element to the end of the array:

Arrays in JavaScript have a default property length, which represents the length of the array. In addition to the length attribute, JS also provides the push() method. Using this method, we can directly add an element at the end.

arr.push('Jake')

clipboard.png

So what is the complexity of this command? We know that by default, JS provides the length attribute. push() equivalent to using the following command:

arr[arr.length - 1] = 'Jake'

Because we can always access the length property of the array, no matter how big the array is, the complexity of adding an element at the end is always O(1) 👏.

Add an element at the beginning of the array:

For this operation, JavaScript provides a unshift() , which adds the element to the beginning of the array.

let arr = ['John', 'Lily', 'William', 'Cindy']
arr.unshift('Robert')
console.log(arr) // [ 'Robert', 'John', 'Lily', 'William', 'Cindy' ]

unshift complexity of the 060e3960016dbf method seems to be the same as the complexity of the push O(1) , because we just add an element in front. This is not the case, let us see what unshift when using the 060e3960016dc2 method:

clipboard.png

In the above figure, when we use the unshift method, the index of all elements should increase by . Here we have a relatively small number of arrays, and no problems can be seen. Imagine using a fairly long array. Then, using unshift will cause a delay because we have to move the index of each element in the array. Therefore, the complexity of the unshift O(n) 😋.

If you want to deal with larger length arrays, use the unshift method wisely. To add an element at a specific index, we can use the splice() method. Its syntax is as follows:

splice(startingIndex, deleteCount, elementToBeInserted)

Because we are adding an element, deleteCount will be 0 . For example, if we want to add a new element to the array index 2, we can use it like this:

let arr = ['John', 'Lily', 'William', 'Cindy']
arr.splice(2, 0, 'Janice')
console.log(arr)
// [ 'John', 'Lily', 'Janice', 'William', 'Cindy' ]

Do you think the complexity of this operation is how much? In the above operation, we in the index 2 added elements, and are therefore, in the index 2 any subsequent elements after must add or remove 1 (comprising, prior to the index element at 2 ).

clipboard.png

It can be observed that we are not moving or incrementing the index of all elements, but incrementing the index of the element after the 2 Does this mean that the complexity of the operation is `O(n/2)? Not 😮. According to the Big O rule, constants can be removed from complexity, and we should consider the worst case. Therefore, the complexity of this operation is O(n) 😳.

Delete element:

Just like adding elements, deleting elements can be done at different positions, at the end, the beginning, and at a specific index.

delete an element at the end of the array:

Like push( ) , JavaScript provides a default method pop() to delete/delete elements at the end of the array.

let arr = ['Janice', 'Gillian', 'Harvey', 'Tom']
arr.pop()
console.log(arr)
// [ 'Janice', 'Gillian', 'Harvey' ]

arr.pop()
console.log(arr)
// [ 'Janice', 'Gillian' ]

The complexity of this operation is O(1) . Because, no matter how big the array is, deleting the last element does not need to change the index of any element in the array.

Delete an element at the beginning of the array:

JavaScript provides a default method of shift() , which deletes the first element of the array.

let arr = ['John', 'Lily','William','Cindy']
arr.shift()
console.log(arr) // ['Lily','William','Cindy']
arr.shift()
console.log(arr);// ['William','Cindy'] 

clipboard.png

From the above we can easily see that the complexity of the shift() O(n) , because after deleting the first element, we must shift or decrement the index of all elements by 1 .

is deleted at a specific index:

For this operation, we use the splice() method again, but this time, we only use the first two parameters because we do not intend to add new elements at this index.

let arr = ['Apple', 'Orange', 'Pear', 'Banana','Watermelon']
arr.splice(2,1)
console.log(arr) // ['Apple', 'Orange', 'Banana','Watermelon']

Similar to the operation of adding elements with splice , in this operation, we will decrement or move 2 , so the complexity is O(n) .

Find element:

Lookup is just to access an element of the array, we can access the elements of the array by using square bracket notation (for example: arr[4] ).

What do you think is the complexity of this operation? Let's demonstrate through an example:

let fruits = ['Apple', 'Orange', 'Pear']

clipboard.png

We have seen earlier that all elements of the array are stored in order and are always grouped together. Therefore, if you execute fruits[1] , it will tell the computer to find fruits and get the second element (the array starts at index 0 ).

Because they are stored in order, the computer does not have to look at the entire memory to find the element, because all elements are grouped together in order, so it can be viewed directly inside the fruits array. Therefore, the complexity of the search operation in the array is O(1) .

We have completed the basic operations on arrays, let's first summarize when we can use arrays:

When you want to perform operations like push() (add elements to the end) and pop() (remove elements from the end), arrays are suitable because the complexity of these operations is O(1) .

In addition, the search operation can be performed very quickly in the array.

When using arrays, operations such as adding/removing elements at a specific index or at the beginning can be very slow, because their complexity is O(n) .

Object

Like arrays, objects are one of the most commonly used data structures. The object is a hash table that allows us to store key-value pairs instead of storing the values at the index of the number as we see in the array.

The simplest way to define an object is:

let obj1 = {}

case:

let student = {
    name: 'Vivek',
    age: 13,
    class: 8
}

Let's take a look at how the above objects are stored in memory:

clipboard.png

As you can see, the key-value pair of the object is randomly stored , unlike all elements in the array are stored together. This is also the main difference between arrays and objects. In objects, key-value pairs are randomly stored in memory.

We also see that there is a hash function (hash function) . So what does this hash function do? The hash function obtains each key from the object and generates a hash value, and then converts this hash value into the address space, where the key-value pair is stored.

For example, if we add the following key-value pair to the student object:

student.rollNumber = 322

rollNumber key passes through a hash function and then converted into an address space for storing keys and values. Now that we have a basic understanding of how objects are stored in memory, let's perform some operations.

Add to

For objects, we don't have a separate way to add elements to the front or back, because all key-value pairs are stored randomly. The only operation is to add a new key-value pair to the object.

case:

student.parentName = 'Narendra Singh Bisht'

clipboard.png

From the above figure, we can conclude that the complexity of this operation is always O(1) , because we do not need to change any index or the operation object itself, we can directly add a key-value pair, which is stored in A random address space.

delete

Like adding elements, the deletion of objects is very simple, with a complexity of O(1) . Because we don't have to change or manipulate objects when deleting.

delete student.parentName

Find

The complexity of the lookup is O(1) , because here, we only use the key to access the value. One way to access the value in the object:

student.class

The complexity of adding, deleting and looking up objects is O(1) ??? So can we conclude that we should use objects instead of arrays every time? The answer is no. Although the object is great, there are some small things to consider when using the object, that is, Hash Collisions . When working with objects, this situation should not always be handled, but understanding the situation helps us better understand the object.

So what is hash collision ?

When we define an object, our computer allocates some space for the object in memory. We need to remember that the space in our memory is limited, so it is possible that two or more key-value pairs may have the same address space. This situation is called a hash collision. In order to understand it better, let's look at an example:

Assume that 5 blocks of space are allocated for the following objects

clipboard.png

We observe that the two key-value pairs are stored in the same address space. How could this be? This happens when the hash function returns a hash value that is converted to the same address space for multiple keys. Therefore, multiple key are mapped to the same address space. Due to hash collisions, the complexity of adding and accessing object values is O(n) , because to access specific values, we may have to traverse various key-value pairs.

Hash collision not something we need to deal with every time we use an object. This is only a special case, which also shows that the object is not a perfect data structure.

In addition to *hash collisions, there is another situation that must be paid attention to when using objects. JS provides us with a built-in keys() method for traversing the keys of an object.

We can apply this method to any object, for example: object1.keys() . keys() method traverses the object and returns all keys. Although this method looks simple, we need to understand that the key-value pairs in the object are randomly stored in memory. Therefore, the process of traversing the object becomes slower, which is different from traversing the array that groups them together in order. .

To summarize, when we want to perform operations such as adding, deleting, and accessing elements, we can use objects, but when using objects, we need to traverse the objects carefully because this can be time-consuming. In addition to traversal, we should also understand that sometimes due to the hash collision , the complexity of accessing the object operation may become O(n) .


possible bugs after code deployment cannot be known in real time. In order to solve these bugs afterwards, a lot of time was spent on log debugging. By the way, I would like to recommend a useful BUG monitoring tool Fundebug .

Original: https://blog.soshace.com/comparing-data-structures-in-javascript-arrays-vs-objects/

communicate with

If you have dreams and dry goods, search for [Great Move to the World] Follow this wise brush who is still doing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line interview complete test site, information and my series of articles.


王大冶
68k 声望104.9k 粉丝