Techmaster Việt Nam – Học là có việc

Đọc nhanh thôi, tôi hứa. Trong vài tháng qua, tôi đã nhận thấy chính xác là có bốn lỗi vẫn tiếp tục quay trở lại thông qua các câu hỏi và tôi đã kiểm tra lại. Tôi đăng bài viết này bởi vì tôi cũng đã mắc phải tất cả những lỗi này! Hãy duyệt qua chúng để đảm bảo rằng chúng ta sử dụng đúng các method của Mảng!

“Nếu bạn đang tìm kiếm thứ gì đó trong mảng của mình, hãy sử dụng Array.indexOf “. Tôi nhớ là đã đọc một câu như thế này trong khóa học của mình khi tôi đang học JavaScript. Câu này khá đúng, không nghi ngờ gì!

Array.indexOf “trả về chỉ mục(vị trí) đầu tiên mà tại đó một phần tử đã cho có thể được tìm thấy”, tài liệu MDN nói. Vì vậy, nếu chúng ta sử dụng chỉ số được trả về sau trong Code của chúng ta, và Array.indexOf là giải pháp.

Tuy nhiên, nếu chúng ta chỉ cần biết liệu mảng của chúng ta có chứa một giá trị nào đó hay không? Có vẻ như đây là một câu hỏi dạng Yes/No,tôi sẽ nói đây là một câu hỏi Boolean. Trong trường hợp này, tôi khuyên bạn nên sử dụng Array.includes trả về một Boolean.

'use strict';

const characters = [
  'ironman',
  'black_widow',
  'hulk',
  'captain_america',
  'hulk',
  'thor',
];

console.log(characters.indexOf('hulk'));
// 2
console.log(characters.indexOf('batman'));
// -1

console.log(characters.includes('hulk'));
// true
console.log(characters.includes('batman'));
// false

 

Sử dụng Array.find thay vì Array.filter

Array.filter là một method rất hữu ích. Nó tạo ra một mảng mới từ một mảng đã có với tất cả các mục đi qua đối số gọi lại.Giống như cái tên của nó, chúng ta sử dụng phương pháp này để lọc và nhận được một mảng ngắn hơn.

Tuy nhiên, nếu chúng ta biết chắc rằng hàm Callback của chúng ta chỉ có thể trả về một mục duy nhất, tôi sẽ không khuyến nghị nó – Ví dụ khi sử dụng một đối số gọi lại lọc qua một ID duy nhất. Trong trường hợp này, Array.filter sẽ trả về một mảng mới chỉ chứa một mục duy nhất. Bằng cách tìm kiếm một ID cụ thể, ý định của chúng tôi có thể là sử dụng giá trị duy nhất chứa trong mảng, điều này làm cho mảng trở nên vô dụng.

Hãy nói về hiệu suất. Để trả về tất cả các mục khớp với hàm gọi lại, Array.filter phải duyệt toàn bộ mảng. Hơn nữa, hãy tưởng tượng rằng chúng ta có hàng trăm giá trị thỏa mãn đối số gọi lại. Mảng lọc của chúng ta sẽ khá lớn.

Để tránh những tình huống này, tôi khuyên bạn nên sử dụng Array.find. Nó cũng đòi hỏi một đối số gọi lại như Array.filter, và nó trả về giá trị của phần tử đầu tiên đáp ứng yêu cầu gọi lại này.Tuy nhiên Array.find sẽ dừng lại ngay sau khi có một mục đáp ứng yêu cầu gọi lại. Không cần duyệt toàn bộ mảng. Ngoài ra, bằng cách sử dụng Array.find để tìm một mục, chúng ta đưa ra một ý tưởng rõ ràng hơn về ý định của mình.

'use strict';

const characters = [
  { id: 1, name: 'ironman' },
  { id: 2, name: 'black_widow' },
  { id: 3, name: 'captain_america' },
  { id: 4, name: 'captain_america' },
];

function getCharacter(name) {
  return character => character.name === name;
}

console.log(characters.filter(getCharacter('captain_america')));
// [
//   { id: 3, name: 'captain_america' },
//   { id: 4, name: 'captain_america' },
// ]

console.log(characters.find(getCharacter('captain_america')));
// { id: 3, name: 'captain_america' }

 

Thay thế Array.find bằng Array.some.

Tôi thừa nhận rằng tôi đã mắc lỗi này nhiều lần. Sau đó, một người bạn tốt bụng bảo tôi kiểm tra lại tài liệu MDN tốt hơn. Vấn đề là : điều này rất giống với trường hợp Array.indexOf / Array.includes của chúng ta ở trên.

Trong trường hợp trước, chúng ta đã thấy Array.find yêu cầu một cuộc gọi lại làm đối số và trả về một phần tử. Array.find là giải pháp tốt nhất nếu chúng ta cần phải biết liệu mảng của chúng ta có chứa một giá trị hay không? Có lẽ không, bởi vì nó trả về một giá trị, không phải là một boolean.

Đối với trường hợp này, tôi khuyên bạn nên sử dụng Array.some trả về boolean. Ngoài ra, về mặt ngữ nghĩa, việc sử dụng Array.some nhấn mạnh rằng chúng ta không cần mục tìm thấy.

'use strict';

const characters = [
  { id: 1, name: 'ironman', env: 'marvel' },
  { id: 2, name: 'black_widow', env: 'marvel' },
  { id: 3, name: 'wonder_woman', env: 'dc_comics' },
];

function hasCharacterFrom(env) {
  return character => character.env === env;
}

console.log(characters.find(hasCharacterFrom('marvel')));
// { id: 1, name: 'ironman', env: 'marvel' }

console.log(characters.some(hasCharacterFrom('marvel')));
// true

Sử dụng Array.reduce thay vì Array.filter và Array.map

Hãy đối diện với nó, Array.reduce không đơn giản để hiểu. Đúng rồi! Nhưng, nếu chúng ta chạy Array.filter sau đó là Array.map, có cảm giác như chúng ta đang thiếu cái gì đó, đúng không?

Ý tôi là,ở đây chúng ta đã duyệt qua mảng hai lần. Lần đầu tiên để lọc và tạo một mảng ngắn hơn, lần thứ hai để tạo một mảng mới (một lần nữa!) chứa các giá trị mới dựa trên các giá trị chúng ta thu được từ Array.filter. Để có được mảng mới, chúng ta đã sử dụng hai phương thức Array. Mỗi phương thức có hàm gọi lại riêng của nó và một mảng mà chúng ta không thể sử dụng sau này – một mảng được tạo bởi Array.filter.

Để tránh hiệu suất thấp, lời khuyên của tôi là sử dụng Array.reduce để thay thế. Cùng một kết quả, mã tốt hơn! Array.reduce cho phép chúng ta lọc và thêm các mục thỏa mãn vào một bộ tích lũy. Ví dụ, bộ tích lũy này có thể là một số để tăng, một đối tượng để lấp đầy, một chuỗi hoặc một mảng để concat.

Trong trường hợp của chúng ta, vì chúng ta đã sử dụng Array.map, tôi khuyên bạn nên sử dụng Array.reduce với một mảng để concat như một bộ tích lũy. Trong ví dụ sau, tùy thuộc vào giá trị của env, chúng ta sẽ thêm nó vào bộ tích lũy của chúng ta hoặc để lại bộ tích lũy này.

'use strict';

const characters = [
  { name: 'ironman', env: 'marvel' },
  { name: 'black_widow', env: 'marvel' },
  { name: 'wonder_woman', env: 'dc_comics' },
];

console.log(
  characters
    .filter(character => character.env === 'marvel')
    .map(character => Object.assign({}, character, { alsoSeenIn: ['Avengers'] }))
);
// [
//   { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] },
//   { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] }
// ]

console.log(
  characters
    .reduce((acc, character) => {
      return character.env === 'marvel'
        ? acc.concat(Object.assign({}, character, { alsoSeenIn: ['Avengers'] }))
        : acc;
    }, [])
)
// [
//   { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] },
//   { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] }
// ]

That’s it!

Hi vọng điêu nay co ich. Hãy chắc chắn để lại ý kiến ​​nếu bạn có bất kỳ suy nghĩ về bài viết này hoặc có bất kỳ trường hợp sử dụng khác để hiển thị. Và nếu bạn thấy nó hữu ích, hãy cho tôi một số vỗ tay 👏 và chia sẻ nó. Cảm ơn vì đã đọc!

Lưu ý: Vấn đề đã được đề cập bởi malgosiastp và David Piepgrass trong các ý kiến, hãy kiểm tra sự hỗ trợ trước khi sử dụng Array.find và Array.includes, hiện không được hỗ trợ bởi Internet Explorer.

Nguồn: https://medium.freecodecamp.org/heres-how-you-can-make-better-use-of-javascript-arrays-3efd6395af3c