Cách tìm max id trong một mảng các đối tượng trong JavaScript

javascript

(Ninh Quang Nguyen) #1

Trong dự án thực tế của bạn, bạn đã bao giờ gặp tình huống tương tự như tiêu đề bài viết của mình chưa? nếu chưa thì sau đây mình sẽ giới thiệu với mọi người về một vài cách để giải quyết vấn đề này

Trong bài viết này mình sẽ hướng dẫn bạn qua 4 cách:

  • Array.forEach
  • Array.map
  • Array.reduce
  • Math.max

Đầu tiên thì chúng ta hãy tạo ra “vấn đề” trước đã. Mình sẽ tạo 1 mảng

const characters = [
  { id: 1, first: "con", last: "ga" },
  { id: 17, first: "con", last: "chuot" },
  { id: 199, first: "con", last: "meo" },
  { id: 75, first: "ca", last: "heo" },
  { id: 444, first: "con", last: "cho" },
  { id: 95, first: "con", last: "bo" },
  { id: 186, first: "con", last: "trai" },
  { id: 364, first: "con", last: "gai" },
  { id: 285, first: "con", last: "chim" },
  { id: 33, first: "con", last: "so" }
];

1. Array.forEach

Suy nghĩ đầu tiên của bạn có thể dùng vòng lặp trên mảng bằng cách sử dụng một số loại vòng lặp tất nhiên rồi, đó là những gì bạn đã được dạy để làm kể từ khi bạn bắt đầu code. Bạn có thể bắt đầu bằng cách khai báo max bằng 0, lặp lại trên mỗi character và nếu id của nó lớn hơn max, thì cập nhật max.

let max = 0;
characters.forEach(character => {
  if (character.id > max) {
    max = character.id;
  }
});
alert(max)

chắc chắn code sẽ hoạt động nhưng tưởng tượng bạn có hàng nghìn hoặc hàng triệu object trong mảng thì …

2. Array.map

Bất cứ khi nào 1 vấn đề có thể xử lý bằng 1 vòng lặp thì có lẽ chúg ta cũng nên xem xét xem nó có thể xử lý bằng map/filter/reduce. Phương thức map () tạo ra một mảng mới với kết quả gọi một hàm được cung cấp trên mọi phần tử trong mảng gọi. Bạn sẽ sử dụng phương thức map để tạo một mảng mới chỉ chứa id để bạn không còn làm việc với các đối tượng nữa. Tại thời điểm này, bạn chỉ cần sử dụng phương thức sắp xếp bình thường trên mảng, lấy phần tử cuối cùng trong danh sách và đó là max id của bạn.

const ids = characters.map(user => user.id);
const sorted = ids.sort((a, b) => a - b);
alert(sorted[sorted.length - 1]);

3. Array.reduce

Phương thức reduce() thức hiện 1 fuction (do chúng ta tạo ra) trên mỗi phần tử của mảng, ở đây ta sẽ gọi reduce cho mảng charecters. Mỗi lần callback function được gọi nó sẽ trả về 1 giá trị và lưu nó là max. phương thức callback kiểm tra id charecter nếu nó lơn hơn max trả về nó, nếu không trả về max

const maxId = characters.reduce(
  (max, character) => (character.id > max ? character.id : max),
  characters[0].id
);
alert(maxId);

bạn có thể sẽ thấy tư tưởng nó khá giống vs forEach nhưng thực tế nó sẽ nhanh hơn nhiều theo mình hiểu thì nó sẽ không phải gán lại giá trị cho biến max mà ở đây kết quả trả về ở lần gọi function trc sẽ được dùng luôn là đầu vào cho lần gọi function tiếp theo

4. Math.max

Nếu bạn tìm hiểu sâu về Math.max, bạn sẽ thấy rằng nó có thể lấy một danh sách các số hoặc một mảng các số. Điều này có nghĩa là tất cả những gì bạn phải làm là lấy một mảng id và bạn có thể chuyển nó vào hàm max (). Nếu bạn chú ý, bạn sẽ thấy nó có tư tưởng giống với map. Điều này có nghĩa là bạn có thể sử dụng hàm map để lấy một mảng id và sau đó chuyển nó vào hàm max ().

alert(Math.max(...characters.map(user => user.id)));

5. thử kiểm tra về hiệu năng

sử dụng console.time () & console.timeEnd ()) và tìm thấy các kết quả sau.

  • ForEach: 0,217ms
  • map: 0.191ms
  • reduce: 0.144ms
  • Math.max: 0,148ms

(Huy Nguyễn) #2

Với for loop thì sao nhỉ. Còn map xong sort sao vẫn nhanh hơn foreach?


(kiencon) #3

sao ko dùng for loop như bạn trên nói, O(n)! dùng time để đánh giá đôi khi không chính xác!


(rogp10) #4

Chắc phải chạy 10000 lần :smiley: chứ 1 lần ko thuyết phục.


83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?