Latest Post

Tăng thứ hạng và truy cập tự nhiên với 10 phương pháp SEO hay nhất Kiếm Tiền Online (mmo): Khái Niệm và Các Hình Thức Phổ Biến
Tổng hợp các phương thức xử lý Array bạn nên biết khi học React
Tổng hợp các phương thức xử lý Array bạn nên biết khi học React

Để nội dung bài viết này thêm dễ hiểu, chúng ta sẽ cùng nhau viết lại toàn bộ các built-in method trong array để có cái nhìn thật là sâu sắc và đúng đắn về những method đi kèm với array trong quá trình sử dụng tránh trường hợp sử dụng theo thói quen hoặc theo người hướng dẫn chỉ bảo mà không biết gì về nó.

Lưu ý: Trong bài viết sẽ sử dụng cú pháp ES6 để code trở nên đơn giản, bạn nên tìm hiểu về các cú pháp nâng cao trong javascript trước khi đọc bài này. Và bài viết sẽ không viết lại đối với những phương thức đơn giản ví dụ: push, pop, shift, unshift

Bài viết chỉ mang tính chất để hiểu các phương thức trong Array, việc áp dụng nó tùy thuộc vào bài toán thực tế vì thế các bạn nên cố gắng tự hiểu từ những cách viết lại sau để có thể hiểu rõ về nó. Bài viết chỉ dành cho những bạn đã hiểu cơ bản về javascript hoặc các bạn đã học khóa Frontend Zero.

concat()

Ghép nối các item vào mảng, nhận tham số là các item hoặc một mảng khác

function concat(arr, ...params) {
    let newArray = []
    for (let i = 0; i < params.length; i++) {
        if (Array.isArray(params[i])) {
            newArray = [...newArray, ...params[i]]
        } else {
            newArray = [...newArray, params[i]]
        }
    }
    return newArray
}

let arr = [1]
concat(arr, 2, 3, [56, 46, 765], { a: 1 }) // [2, 3, 56, 46, 765, { a: 1 }]

//arr => [1]

Lưu ý: concat sẽ tạo ra một array mới mà không tác động vào array truyền vào function.

entries()

Hàm entries trong mảng trả về một đối tượng Iterator chứa cặp giá trị [index, value] của từng phần tử trong mảng.

function entries(array) {
    let index = 0;

    return {
        next: function () {
            return index < array.length ?
                { value: [index++, array[index - 1]], done: false } :
                { value: undefined, done: true };
        }
    };
};

every()

Hàm every được sử dụng để kiểm tra xem tất cả các phần tử trong mảng có thỏa mãn một điều kiện nào đó hay không. Nếu tất cả các phần tử thỏa mãn điều kiện, hàm trả về true, ngược lại hàm trả về false

function every(array, callback, thisArg) {
    let array = this;
    let length = array.length;

    for (let i = 0; i < length; i++) {
        if (!callback.call(thisArg, array[i], i, array)) {
            return false;
        }
    }

    return true;
};

Lưu ý: Hàm sẽ trả về false ngay lặp tức nếu có bất kỳ item nào không đạt điều kiện, vì thế không dùng every để loop qua các item

fill()

Hàm fill trong array được sử dụng để thay đổi tất cả các phần tử trong mảng bằng một giá trị cụ thể.

function fill(array, value, start = 0, end = array.length) {

    for (let i = start; i < end; i++) {
        array[i] = value;
    }

    return array;
};

filter()

Hàm filter được sử dụng để tạo ra một mảng mới chứa các phần tử thỏa mãn một điều kiện nào đó được xác định bởi một hàm callback

function filter(array, callback, thisArg) {
    let length = array.length;
    let result = [];

    for (let i = 0; i < length; i++) {
        if (callback.call(thisArg, array[i], i, array)) {
            result.push(array[i]);
        }
    }

    return result;
};

find()

Hàm find được sử dụng để trả về giá trị của phần tử đầu tiên trong mảng thỏa mãn một điều kiện nào đó được xác định bởi một hàm callback.

function find(array, callback, thisArg) {
    let length = array.length;

    for (let i = 0; i < length; i++) {
        if (callback.call(thisArg, array[i], i, array)) {
            return array[i];
        }
    }

    return undefined;
};

findIndex()

Hàm findIndex được sử dụng để trả về chỉ mục của phần tử đầu tiên trong mảng thỏa mãn một điều kiện nào đó được xác định bởi một hàm callback. Nếu không có phần tử nào thỏa mãn điều kiện, hàm sẽ trả về -1.

function findIndex(array, callback, thisArg) {
    let length = array.length;

    for (let i = 0; i < length; i++) {
        if (callback.call(thisArg, array[i], i, array)) {
            return i;
        }
    }

    return -1;
}

forEach()

Hàm forEach được sử dụng để thực hiện một hành động cho mỗi phần tử trong mảng, không trả về giá trị mới.

function forEach(array, callback, thisArg) {
    let length = array.length;

    for (let i = 0; i < length; i++) {
        callback.call(thisArg, array[i], i, array);
    }
}

from()

Hàm from được sử dụng để tạo một mảng mới từ một đối tượng có thể lặp lại hoặc từ một chuỗi

function from(arrayLike, mapFn, thisArg) {
    let result = [];

    if (typeof mapFn === 'function') {
        for (let [index, value] of arrayLike.entries()) {
            result.push(mapFn.call(thisArg, value, index, arrayLike));
        }
    } else {
        for (let value of arrayLike) {
            result.push(value);
        }
    }

    return result;
};

includes()

Hàm includes được sử dụng để kiểm tra xem một giá trị có tồn tại trong mảng hay không

function includes(array, value) {
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] === value) {
            return true;
        }
    }
    return false;
}

Lưu ý: Giống hàm some nhưng cách sử dụng khác nhau và hàm some linh động hơn do sử dụng callback

indexOf()

Hàm indexOf được sử dụng để tìm kiếm vị trí đầu tiên của một phần tử trong mảng

function indexOf(array, value) {
    for (let i = 0; i < array.length; i++) {
        if (array[i] === value) {
            return i;
        }
    }
    return -1;
}

Giống hàm findIndex() nhưng khác nhau về cách so sánh, findIndex() linh động hơn do sử dụng callback

isArray()

Hàm isArray của đối tượng Array được sử dụng để kiểm tra xem một biến có phải là một mảng hay không

function isArray(array) {
    return typeof array === 'object' && array !== null && 'length' in array;
}

Thông thường nếu các bạn viết như thế này sẽ không sai, nhưng không hoàn toàn đúng. Vì nếu các bạn truyền vào một object có thuộc tính length thì xem như hàm này đã bị sai. Sẽ có một cách khác tối ưu hơn sẽ được liệt kê bên dưới:

function isArray(array) {
    return Object.prototype.toString.call(array) === '[object Array]';
}

Phương pháp này sẽ kiểm tra xem biến có phải là một mảng hay không bằng cách sử dụng Object.prototype.toString.call() để lấy chuỗi đại diện cho kiểu dữ liệu của biến đó, sau đó so sánh chuỗi đó với chuỗi ‘[object Array]‘. Nếu chuỗi đại diện cho kiểu dữ liệu của biến đó là ‘[object Array]‘, nghĩa là biến đó là một mảng, và hàm sẽ trả về true. Nếu không, hàm sẽ trả về false.

join()

Hàm join() trong đối tượng Array được sử dụng để nối tất cả các phần tử trong mảng thành một chuỗi

function join(array, separator = ',') {
    let result = '';
    for (let i = 0; i < array.length; i++) {
        result += array[i];
        if (i < array.length - 1) {
            result += separator;
        }
    }
    return result;
}

keys()

Hàm keys() được sử dụng để trả về một mảng các chỉ mục (key) của tất cả các phần tử trong mảng

function keys(array) {
    const keys = [];
    for (let i = 0; i < array.length; i++) {
        keys.push(i);
    }
    return keys;
}

lastIndexOf()

Hàm lastIndexOf() được sử dụng để trả về key cuối cùng tìm thấy của một phần tử trong mảng

function lastIndexOf(array, searchElement, fromIndex = array.length - 1) {
    for (let i = fromIndex; i >= 0; i--) {
        if (array[i] === searchElement) {
            return i;
        }
    }
    return -1;
}

map()

Hàm map() được sử dụng để tạo ra một mảng mới bằng cách thực hiện một hàm cho từng phần tử trong mảng ban đầu

function map(array, callback) {
    const newArr = [];
    for (let i = 0; i < array.length; i++) {
        newArr.push(callback(array[i], i, array));
    }
    return newArr;
}

Hàm map() này nhận vào một mảng và một hàm callback và trả về một mảng mới được tạo ra bằng cách thực hiện hàm callback cho từng phần tử trong mảng ban đầu. Hàm callback này nhận vào ba đối số là giá trị của phần tử hiện tại, index của phần tử đó trong mảng và mảng gốc.

Hàm map() được sử dụng rất nhiều trong React là vì nó trả về một mảng mới được tạo từ callback vì thế thường được sử dụng để render một array các element trong React.

reduce()

Hàm reduce() được sử dụng để tích lũy các giá trị của mảng thành một giá trị duy nhất thông qua việc thực hiện một hàm callback trên từng phần tử của mảng

function reduce(array, callback, initialValue) {
    let accumulator = initialValue === undefined ? array[0] : initialValue;
    for (let i = initialValue === undefined ? 1 : 0; i < array.length; i++) {
        accumulator = callback(accumulator, array[i], i, array);
    }
    return accumulator;
}

Hàm reduce() này nhận vào một hàm callback và giá trị khởi tạo (nếu có) và trả về một giá trị duy nhất được tính toán bằng cách thực hiện hàm callback trên từng phần tử của mảng.

Cách viết lại này sử dụng một biến accumulator để tích lũy các giá trị của mảng. Nếu giá trị khởi tạo được cung cấp, accumulator sẽ được khởi tạo bằng giá trị này; nếu không, accumulator sẽ được khởi tạo bằng phần tử đầu tiên của mảng. Sau đó, vòng lặp sẽ bắt đầu từ phần tử thứ hai (nếu có) và thực hiện hàm callback trên mỗi phần tử, với accumulator, giá trị của phần tử đó, chỉ mục và mảng gốc được truyền vào hàm callback. Kết quả trả về từ hàm callback được tích lũy vào biến accumulator. Khi vòng lặp hoàn tất, accumulator sẽ chứa giá trị tích lũy cuối cùng, và giá trị này sẽ được trả về.

reduceRight()

Tương tự như reduce(), nhưng khác nhau duy nhất là reduceRight() duyệt mảng từ bên phải sang bên trái (cuối mảng đến vị trí số 0)

function reduceRight(array, callback, initialValue) {
    let accumulator = initialValue === undefined ? array[array.length - 1] : initialValue;
    for (let i = array.length - (initialValue === undefined ? 2 : 1); i >= 0; i--) {
        accumulator = callback(accumulator, array[i], i, array);
    }
    return accumulator;
}

Nếu các bạn chỉ có nhu cầu tích lũy một giá trị trong array đơn giản ví dụ tính tổng thì sử dụng reduce() hay reduceRight() ta nhận được kết quả hoàn toàn giống nhau. Tuy nhiên có một vài trường hợp sử dụng redeceRight() lại thuận tiện hơn, ví dụ cộng chuỗi từ bên phải:

const myArray = [1, 2, 3, 4, 5];

// Sử dụng reduce():
const sum1 = reduce(myArray, (accumulator, currentValue) => accumulator + currentValue);
console.log(sum1); // 15

// Sử dụng reduceRight():
const sum2 = reduceRight(myArray, (accumulator, currentValue) => accumulator + currentValue);
console.log(sum2); // 15

const myArrayString = ['!', 'Spacedev', 'Hello'];

// Sử dụng reduceRight() để nối các chuỗi từ phải sang trái:
const greeting = reduceRight(myArrayString, (accumulator, currentValue) => accumulator + ' ' + currentValue);
console.log(greeting); // 'Hello Spacedev !'

reverse()

Hàm reverse() được sử dụng để đảo ngược thứ tự các phần tử trong một mảng

function reverse(array) {
    for (let i = 0; i < array.length / 2; i++) {
        [array[i], array[array.length - 1 - i]] = [array[array.length - 1 - i], array[i]]
    }
    return array;
}

Lưu ý: Hàm reverse() sẽ thay đổi trên mảng gốc

slice()

Hàm slice() được sử dụng để trích xuất một phần của mảng và trả về một mảng mới chứa các phần tử đã trích xuất đó

function slice(array, start = 0, end = array.length) {
    const result = [];
    for (let i = start; i < end && i < array.length; i++) {
        result.push(array[i]);
    }
    return result;
}

some()

Hàm some() được sử dụng để kiểm tra xem có ít nhất một phần tử trong mảng thỏa mãn một điều kiện nào đó hay không. Ở đây mình sử dụng đệ quy cho nó mới lạ

function some(array, callback, index = 0) {
    if (index >= array.length) {
        return false;
    }
    return callback(array[index], index, array) || some(array, callback, index + 1);
}

sort()

Hàm sort() được sử dụng để sắp xếp các phần tử trong mảng theo một thứ tự nào đó. Chúng ta có thể viết lại hàm này bằng cách sử dụng một số thuật toán sắp xếp có sẵn hoặc tự viết thuật toán sắp xếp.

Do trong phạm vi bài viết này, chúng ta không bàn về cách sắp xếp như thế nào cho nhanh mà chỉ bàn về chức năng của phương thức sort()

function sort(array, callback) {
    for (let i = 0; i < array.length - 1; i++) {
        for (let j = i + 1; j < array.length; j++) {
            if (!callback) {
                if (arr[i] > arr[j]) {
                    [array[i], array[j]] = [array[j], array[i]]
                }
                continue;
            }
            if (callback(array[i], array[j]) < 0) {
                [array[i], array[j]] = [array[j], array[i]]
            }
        }
    }
    return array;
}

Hàm sort nhận vào một callback có chức năng quyết định sự sắp xếp, hàm hàm sort() hoạt động dựa vào hàm callback return 3 loại giá trị sau đây;

  • Nếu hàm trả về giá trị là 0: hai phần tử được coi là bằng nhau và không thay đổi vị trí của chúng trong mảng.
  • Nếu hàm trả về giá trị là một số dương (ví dụ: 1): phần tử đứng sau (theo thứ tự sắp xếp trên params truyền vào callback) sẽ được đặt trước phần tử đứng trước.🤣
  • Nếu hàm trả về giá trị là một số âm (ví dụ: -1): phần tử đứng trước (theo thứ tự sắp xếp trên params truyền vào callback ) sẽ được đặt trước phần tử đứng sau. 🤣 

Lưu ý: Hàm sort() của Array thay đổi trên mảng gốc

splice()

Hàm splice trong Javascript dùng để thêm hoặc xóa phần tử trong mảng

function splice(array, start, deleteCount, ...items) {
    const removedItems = array.slice(start, start + deleteCount);
    const afterDelete = array.slice(start + deleteCount);

    array.length = start;
    array.push(...items, ...afterDelete);

    return removedItems;
}

Lưu ý: Hàm splice() thay đổi trên mảng gốc

copyWithin()

Hàm copyWithin() được sử dụng để sao chép một phần tử hoặc một tập hợp các phần tử trong mảng và dán chúng vào vị trí khác trong cùng mảng

function copyWithin(array, target, start = 0, end = array.length) {
    const length = Math.min(end - start, array.length - target);
    let count = 0;

    for (let i = target; i < target + length; i++) {
        array[i] = array[start + count];
        count++;
    }

    return array;
}

Tổng kết

Trên đây là những phương thức có sẵn trong Array chúng ta thường sử dụng trong javascript, việc hiểu rõ cách thức xử lý của những method sẽ giúp các bạn xử lý Array trở nên linh hoạt và giúp rất nhiều trong quá trình học React trở nên dễ dàng hơn.

Cho dù bạn học bất kỳ framework nào của Frontend hoăc là backend Nodejs sử dụng javascript làm ngôn ngữ chính thức đều bắt buộc phải hiểu rõ cách thức hoạt động và các thao tác trên Array.

Không những thế, thao tác với Array là một điều bắt buộc trong lập trình, bất kể ngôn ngữ lập trình bạn đang sử dụng là gì đi chăng nữa, những kiến thức này sẽ luôn luôn theo bạn suốt hành trình làm developer của mình.

Nếu bạn cảm thấy hay hoặc muốn lưu lại, đừng ngần ngại mà không like và chia sẻ cho bạn bè cùng học tập.

2 thoughts on “Tổng hợp các phương thức xử lý Array bạn nên biết khi học React

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *