Array javascript - 4 tính năng mới nhất bao gồm (limit, skip, distinct...)

Nội dung bài viết

Javascript là một ngôn ngữ phổ biến trên thế giới, nếu không nhầm thì nó đã hơn 20 năm, và hơn bao giờ hết nó đang phát triển một cách mạnh mẽ từ front-end đến backend và thậm chí là database(mongodb). Do đó việc chúng ta sử dụng javascript hằng ngày là điều hiển nhiên. Và javascript là một gợi ý tuyệt vời khi phát triển một dự án nhỏ, nhanh gọn, tối ưu cao.

Nhưng... tôi vẫn chưa cảm thấy thực sự sướng mặc dù từ ES6 tới ES11 đã cung cấp cho chúng ta nhiều methods hay feature javascript, nhằm hỗ trợ cho developers có thể xử lý nhanh chóng một số task. Có ai đã từng giống như tôi không, khi làm việc với array hay object trong javascript, thì tôi cảm thấy vẫn còn thiếu sự hỗ trợ nhiệt tình từ javascript. 
Và trong bài viết này, tôi sẽ trình bày 4 tính năng mà theo tôi javascript nên bổ sung để giúp những người khó tính như tôi hoàn thành ước mơ :)

Array javascript - Tính năng mới nhất

Array.findAndRemove()

Đúng, chính xác là tôi muốn nhiều hơn nữa. Nếu bạn muốn remove item in array javascript thì bạn phải sử dụng những cách tối ưu như trong bài viết này: ''Tổng hợp những cách javascript remove element from array"

Còn không bạn sẽ phải sử dụng cách thủ công

Với < ES6

function removeElement(array, elem) {
    var index = array.indexOf(elem);
    if (index > -1) {
        array.splice(index, 1);
    }
}
var arr = [1, 2, 3, 4, 5];
removeElement(arr, 4);
console.log(arr);

// Output:

//  [1, 2, 3, 5]

Với ES6

const items = [1, 2, 3, 4, 5]
const valueToRemove = 4
const filteredItems = items.filter(item => item !== valueToRemove)

Output:
  [1, 2, 3, 5]

Họ có thể phát triển những methods như filter, map, reduce trong javascript nhưng tại sao lại không phát triển thêm medthod như trong Mongodb có cung cấp một tính năng đó là findAndRemove(). Nếu như vậy thì chính những người lập trình viên sẽ không phải đi tìm cách này hay cách kia nữa???? Đúng không? Giờ nó không thêm thì mình thêm. Sau đây tôi sẽ làm một function như vậy cho chính tôi và các bạn sử dụng :

Possible implementation

Array.prototype.findAndRemove = function (value, key = null) {
    const index = this.findIndex(obj => (!!obj[key]) ? obj[key] === value : obj === value);
    return index >= 0 ? [
        ...this.slice(0, index),
        ...this.slice(index + 1)
    ] : this;
}

Cách sử dụng findAndRemove() trong array javascript

const list = [
    {id: 1,"name":"anonystick.com"},
    {id: 2,"name":"medium.com"},
    {id: 3,"name":"facebook.com"}
]
console.log(list.findAndRemove(2, "id")); //remove id = 2

Output:

[{id: 1, name: "anonystick.com"}, {id: 3, name: "facebook.com"}]

Hoặc

const list = [1, 2, 3 , 4, 5]
console.log(list.findAndRemove(2)); //remove item = 2
Output: [1, 3, 4, 5]

Như vậy giờ đây thay vì tôi đi tìm giải pháp cho remove item in array javascript thì tôi sẽ dùng method này. Gợi ý như vậy liệu có ngớ ngẩn???

Array.getIndexes()

Tính năng tiếp theo mà tôi muốn như .indexOf() vậy. Nhưng ở .indexOf() bạn chỉ nhận được một giá trị trả về khi nó tìm thấy đầu tiên, hoặc return về -1 khi nó không tìm thấy. Nhưng ở đây, có rất nhiều trường hợp mà tôi muốn nó sẽ trả về hết index của tất cả những gì được tìm thấy. Ví dụ

const findIndex = [1,2,3,4,3,6,8,3]
console.log(findIndex.indexOf(3))
Output: 2

Đương nhiên rồi, bạn thấy đấy khi dùng indexOf() chỉ return only 1 giá trị index mà thôi, nhìn phát chán. Tại sao những nhà phát triền lại không tích hợp một tính năng find tất cả những index được tìm thấy trong array, giống như Mongodb cũng đã làm đó là getIndexes(). Nó không làm thì chúng ta tự làm :D

Possible implementation

Array.prototype.getIndexes = function(test){
  if(typeof(test) === "function"){
    return this.reduce((indices, element, index) => {
      if (test(element)) indices.push(index)
      return indices
    }, [])
  } else {
    return this.reduce((indices, element, index) => {
      if (element === test) indices.push(index)
      return indices
    }, [])
  }
}

Sử dụng getIndexes() javascript

const findIndex = [1,2,3,4,3,6,8,3]
console.log(findIndex.getIndexes(3))

Output: [2, 4, 7]

Quá ngon cho một cú pháp getIndexes(), nhưng đối với một array object trong javascript thì cũng tương tự mà thôi, ví dụ

const list = [{name: "anonystick"}, {name: "facebook"}, {name: "anonystick"}]
console.log(list.getIndexes(obj => obj.name === 'anonystick'))

Output: [0, 2]

Array.distinct()

Một tính năng thứ ba, mà tôi tin các bạn cũng như tôi đều mong muốn, vì cạc bạn biết không "how to remove duplicate in javascript" trung bình một tháng tìm kiếm trên 5000 lượt. Một con số khổng lồ, ngoài ra còn những tìm kiếm khác như:

  • remove duplicate object in array 
  • javascript filter duplicate objects in array 
  • javascript remove object duplicates 
  • javascript remove duplicate array 
  • javascript es6 remove duplicate values from array object 
  • javascript check duplicate in array 
  • javascript duplicate array object 
  • javascript remove duplicate object js

Wow, điều đó cho thấy tính năng này quan trọng đến mức độ nào, nhưng tại sao javascript lại không hỗ trợ những điều này. Buộc tôi cũng phải tự tìm cho mình một hướng đi và suggest tới javascript developers luôn.

Nếu như các bạn muốn tự tìm cho mình một giải pháp riêng thì đây: "Remove Duplicates from an Array with ES6", còn nếu như bạn nào đã từng đọc bài viết về "Học javascript bắt đầu từ số 0" thì cũng đã hiểu về cách viết bắt đầu từ vanilla javascript thì có thể nên đọc bài viết này: "Vanilla JavaScript là gì? Remove Duplicates from an Array with vanilla JavaScript"

Ok, và bây giờ tôi cũng giới thiệu một methods của javascript vừa được supports :D

Possible implementation

Array.prototype.distinct = function(selector){
  if (selector === 'undefined'){
    return [...new Set(this)];
  }

  if (typeof(selector) !== 'function'){
    throw new Error(`Expecting selector to be a function, but received ${typeof(selector)} instead.`)
  }
  
  let found = new Set()
  return this.filter(element => {
    if (found.has(selector(element))){
      return false
    } else {
      found.add(selector(element))
      return true
    }
  })
}

Cách sử dụng Array.distinct()

const array = [1, 1, 1, 3, 3, 2, 2]
console.log(array.distinct())
Output: [1, 3, 2]

Cách sử dụng Array.distinct() với array object javascript - Khi nào nên sử dụng object, khi nào nên sử dụng array trong javascript

const arr = [
 { id: 1, name: "king" },
 { id: 2, name: "master" },
 { id: 3, name: "lisa" },
 { id: 4, name: "ion" },
 { id: 5, name: "jim" },
 { id: 6, name: "gowtham" },
 { id: 1, name: "jam" },
 { id: 1, name: "lol" },
 { id: 2, name: "kwick" },
 { id: 3, name: "april" },
 { id: 7, name: "sss" },
 { id: 8, name: "brace" },
 { id: 8, name: "peiter" },
 { id: 5, name: "hey" },
 { id: 6, name: "mkl" },
 { id: 9, name: "melast" },
 { id: 9, name: "imlast" },
 { id: 10, name: "glow" }
]
console.log(arr.distinct(obj => obj.id))

Để giải quyết vấn đề này theo javascript thuần thì hãy xem bài viết này: "Vanilla JavaScript là gì? Remove Duplicates from an Array with vanilla JavaScript"

Array.limit() và Array.skip()

Bạn nào làm việc với database thì việc này dễ như trở bàn tay. Vì hầu hết tất cả SQL hay noSQL đều hỗ trợ việc này. Nhưng với javascript thì say no. Moẹ chứ, nhưng điều gì làm chúng ta bó tay. Chỉ có con vợ và ví tiền mới làm cho ta bó tay mà thôi.

Possible implementation

function limit(c){
    return this.filter((x,i)=>{
        if(i<=(c-1)){return true}
    })
}
    
Array.prototype.limi t= limit;

function skip(c){
    return this.filter((x,i)=>{
    if(i>(c-1)){return true}
    })
}

Array.prototype.skip = skip;

Cách sử dụng:

const arr = [
 { id: 1, name: "king" },
 { id: 2, name: "master" },
 { id: 3, name: "lisa" },
 { id: 4, name: "ion" },
 { id: 5, name: "jim" },
 { id: 6, name: "gowtham" },
 { id: 1, name: "jam" },
 { id: 1, name: "lol" },
 { id: 2, name: "kwick" },
 { id: 3, name: "april" },
 { id: 7, name: "sss" },
 { id: 8, name: "brace" },
 { id: 8, name: "peiter" },
 { id: 5, name: "hey" },
 { id: 6, name: "mkl" },
 { id: 9, name: "melast" },
 { id: 9, name: "imlast" },
 { id: 10, name: "glow" }
]

Limit()

console.log(JSON.stringify(arr.limit(2))) ;//get giới hạn 2 records

Ouput:

[
    {"id":1,"name":"king"},
    {"id":2,"name":"master"}
]

Skip()

console.log(JSON.stringify(arr.skip(2))) ;//bỏ qua 2 records đầu tiên

Output

[
    {"id":3,"name":"lisa"},
    {"id":4,"name":"ion"},
    {"id":5,"name":"jim"},
    {"id":6,"name":"gowtham"},
    {"id":1,"name":"jam"},
    {"id":1,"name":"lol"},
    {"id":2,"name":"kwick"},
    {"id":3,"name":"april"},
    {"id":7,"name":"sss"},
    {"id":8,"name":"brace"},
    {"id":8,"name":"peiter"},
    {"id":5,"name":"hey"},
    {"id":6,"name":"mkl"},
    {"id":9,"name":"melast"},
    {"id":9,"name":"imlast"},
    {"id":10,"name":"glow"}
]

Mỏi tay quá, thôi gắng viết nốt phần này nữa. Nhưng chúng ta vẫn có thể kết hợp được skip và limit luôn, ví dụ:

Skip() và limit()

console.log(JSON.stringify(arr.skip(2).limit(2)));// bỏ qua 2 records đầu tiên và lấy 2 records đầu tiên

Nghĩa là bỏ 1,2 nhưng lấy 3, 4.

Output:

[
    {"id":3,"name":"lisa"},
    {"id":4,"name":"ion"}
]

Lời kết

Chúng tôi chân thành cảm ơn những nhà phát triển javascript đã tạo một sân chơi với nhiều tính năng, nhưng cũng cố gắng lắng nghe ý kiến của chúng tôi về việc, thêm bớt những tính năng cần thiết chứ chúng tôi khổ quá rồi. Mới đây, javascript vừa công bố kết thúc stage 03, lên stage04 việc này có nghĩa là những tính năng như top-level await, Optional Chaining... Sẽ được phát hành chính thức, tất nhiên không có những methods đó của chúng ta.

Thanks for readding!