Series lập trình với dữ liệu Array và Object trong Javascript - Xử lý dữ liệu như thế nào cho tốt?

Series lập trình với dữ liệu Array và Object trong Javascript - Xử lý dữ liệu như thế nào cho tốt?

Tin ngắn hàng ngày dành cho bạn
  • Có 2 phần mềm tiện ích cho Mac mà mỗi khi dùng máy Mac Mini hoặc Macbook có cắm thêm màn hình rời, thêm bàn phím với chuột nữa là BetterDisplayMac Mouse Fix. Đi qua từng cái nhé!

    BetterDisplay giúp tinh chỉnh kích thước của màn hình rời để đạt độ phân giải HiDPI. Như bạn biết Mac khá kén màn hình và tuỳ chọn độ phân giải trong cài đặt mặc định rất ít ỏi, nên BetterDisplay cung cấp nhiều lựa chọn phù hợp hơn.

    Cái thứ hai là Mac Mouse Fix, nếu dùng chuột ngoài bạn sẽ thấy nó cuộn không giống với Trackpad của Macbook cho lắm. Điều kì diệu xảy ra khi cài phần mềm này vào. Nó thêm hiệu ứng "smooth" và giúp cuộn chuột y như cuộn bằng Trackpad luôn. Thật thần kỳ.

    » Xem thêm
  • Mọi người còn nhớ grep.app không? Trang cho phép tìm kiếm mọi thứ trên Github chỉ cần đoạn mã xuất hiện trong cụm từ tìm kiếm. Sơ qua thì trang này đang lưu lại dữ liệu từ Github hay làm thế nào đó rồi mới tìm kiếm được, do đó không phải 100% kho lưu trữ công khai đều xuất hiện trên này.

    Mình phát hiện ra Github cũng có trang tương tự, hơi chậm tí thôi cơ mà tìm kiếm 100% luôn nha 😆. Github Search. Mọi người nhớ bấm vào Code ở mục Filter By bên trái để nó tìm chính xác hơn nhé.

    » Xem thêm
  • Vừa gia hạn tên miền cho 2coffee.dev. Vậy là em nó đã 3 tuổi rồi đó mọi người. Sẵn đây nói luôn...

    Mọi người chắc cũng biết về ý nghĩa của cái tên rồi đúng không. Ấy thế mà nó lại đang dính vào "lời nguyền cà phê" bởi vì tên miền có chứa từ khoá "coffee" rất "hot", làm nhiều người hoặc công cụ tìm kiếm đánh giá sai lệch về nội dung của trang web 🥲. Nhiều lúc mình muốn tìm cách để "khai tử" cái tên này đi, thay bằng tên khác thì con đường bớt chông gai hơn.

    Tiền thân của 2coffee.dev là estacks.icu, ấy thế mà sao lại bỏ được cái tên cũ không chút đắn đo? Là vì 2coffee.dev đánh dấu sự trưởng thành trong tư duy làm sản phẩm của mình, ý là nghiêm túc hơn á. Còn stacks.icu vẫn mãi mãi là tiền thân của "Xin chào, một tách cà phê dành cho mấy ông lập trình viên đây".

    » Xem thêm

Vấn đề

Lưu ý: Bài viết dưới đây là những quan điểm cá nhân của tôi về vấn đề xử lý dữ liệu. Điều đó cũng bao gồm những kinh nghiệm của tôi trong các dự án thực tế. Các bạn đọc có thể mang tính chất tham khảo hoặc cũng có thể để lại những ý kiến để mọi người cùng thảo luận nhé.

Ở bài viết trước tôi có giới thiệu cho các bạn một vài cách xử lý dữ liệu thì bài viết ngày hôm nay tôi sẽ tập trung hơn vào việc tôi đã xử lý dữ liệu trong Javascript như thế nào, cũng như cách viết code dễ đọc hơn cho việc bảo trì dự án sau này.

Viết code để chạy được thì nhanh nhưng viết để dễ dàng trong bảo trì sau này đòi hỏi người viết phải có được những kinh nghiệm nhất định, đồng thời việc tổ chức mã, luồng cũng sẽ tốn nhiều thời gian hơn một chút. Thời gian để bảo trì một dự án thường sẽ lớn hơn nhiều so với thời gian để phát hành sản phẩm lần đầu tiên, chưa kể sẽ có những người mới tham gia vào dự án. Vì thế nếu tổ chức mã của bạn tốt sẽ tiết kiệm được kha khá thời gian sau này.

Xử lý dữ liệu là điều thường xuyên trong các chức năng của dự án, các bạn có thể hiểu nó bao gồm các hành động như lọc, ánh xạ, biến đổi dữ liệu trong các tập dữ liệu Array hay Object. 4 kĩ thuật tôi thường hay sử dụng dưới đây góp phần giữ cho code của tôi được rõ ràng hơn.

Bất biến

Bất biến có nghĩa là một khi đã khai báo biến rồi thì tuyệt đối không được thay đổi biến đó nữa. Nếu muốn sửa đổi dữ liệu thì hãy sao chép chúng sang một biến khác. Mới nghe thì có vẻ điều này không hợp lý cho lắm bởi biến trong các ngôn ngữ lập trình được phép thay đổi, gán đi gán lại một cách bình thường. Điều này cũng làm tăng hiệu năng, tiết kiệm bộ nhớ hơn so với việc phải tạo thêm nhiều biến nữa.

Trong Javascript không có định nghĩa kiểu của dữ liệu, việc khai báo một biến với từ khóa var hoặc let giúp cho chúng ta có thể dễ dàng thay đổi dữ liệu hoặc thâm chí là kiểu dữ liệu của nó sau này. Điều này tạo nên sự linh hoạt nhưng tác hại đằng sau sự linh hoạt đó có vẻ là nhiều hơn.

Trong một đoạn mã với hàng chục, hàng trăm dòng code thì việc thay đổi dữ liệu của một biến đôi khi sẽ gây khó khăn trong theo dõi giá trị của biến, bạn sẽ phải phân vân việc liệu giá trị của biến bị thay đổi ở đâu không hay thay đổi những gì... Để giải quyết vấn đề này hãy cố gắng sử dụng khai báo const nhiều nhất có thể, khi sử dụng const bạn sẽ không gán lại giá trị cho biến đó được nữa.

Nhưng mình const là chưa đủ, trong Javascript các kiểu dữ liệu không nguyên thủy như Array, Object... có tính tham chiếu. Dữ liệu đó khi được gán vẫn có thể thay đổi được giá trị của các phần tử, thuộc tính bên trong nó. Vì thế đôi khi chẳng may bạn sửa dữ liệu tham chiếu, các biến khác cũng vô tình bị thay đổi theo. Để tìm hiểu kĩ hơn, các bạn có thể đọc bài viết Đôi điều về Object Reference trong Javascript. Nhiều lúc quên thật phiền toái! của tôi trên estacks.

Thay vì update trực tiếp vào dữ liệu tham chiếu, chúng ta nên sao chép "sâu" (deep copy) dữ liệu có tính chất tham chiếu sang một biến khác để xử lý. Tránh việc thay đổi gây ra những lỗi tiềm ẩn sau này.

Tập trung vào làm gì thay vì làm như thế nào

Để giải thích cho điều này, tôi sẽ lấy một ví dụ về một hàm lấy ra thuộc tính name trong một mảng dữ liệu:

const users = [
  {
    name: "A",
    age: 18
  },
  {
    name: "B",
    age: 19
  },
  {
    name: "C",
    age: 20
  },
];

// cách thứ nhất viết một hàm dùng map để lấy ra name
function usersWithName(users) {
  return users.map(function(user) {
    return {
      name: user.name,
    };
  });
};

// cách thứ hai, vẫn dùng map nhưng ứng dụng curry function
const get = (attribute) => (data) => data[attribute];
const usersWithName = users.map(get("name"));

Trong ví dụ tôi có sử dung Curry function, nếu bạn chưa biết về curry function cũng như ứng dụng của nó thì có thể đọc thêm tại Curry function là gì? Một món "cà ri" ngon và làm sao để thưởng thức nó?.

Trở lại với ví dụ trên, tôi có hai cách viết để cùng đạt được kết quả.

Cách thứ nhất là cách viết thông thường, tôi viết theo dòng suy nghĩ cần phải làm từng bước để có kết quả.

Cách thứ hai, thay vì viết theo dòng suy nghĩ thì tôi tạo ra một hàm get dùng để lấy dữ liệu của thuộc tính trong một object, sau đó đưa nó vào hàm map.

Bằng cách thứ hai, nếu chúng ta tạo thói quen định nghĩa những hàm như get sẽ giúp tạo sự thống nhất trong toàn dự án mặt khác người đọc khi thấy get họ cũng hiểu được đoạn mã đó đang làm gì.

Mã tái sử dụng càng nhiều càng tốt

Hãy cố gắng tạo ra những đoạn mã chỉ tập trung vào một chức năng nào đó sẽ giúp cho mã của bạn có thể tái sử dụng lại. Đồng thời nó cũng tạo sự thống nhất trong toàn dự án, điều đó cũng đồng nghĩa với việc khi bạn thấy nó, bạn có thể biết được nó đang làm gì.

Nhìn vào ví trụ trên ở cách thứ hai, hàm get có thể tái sử dụng nhiều lần, thay vì get("name") tôi có thể get("age")... Hơn nữa mỗi khi nhìn thấy hàm get chúng ta có thể biết ngay là nó "lấy giá trị của thuộc tính" thay vì phải đọc một đoạn code dài như cách một để hiểu được người viết đang muốn làm gì.

Áp dụng những thư viện xử lý dữ liệu phổ biến

Những lợi ích của việc tạo ra những đoạn mã có thể tái sử dụng được nhiều lần đã được cộng đồng phát hiện từ rất lâu về trước. Họ đã tạo ra những thư viện gồm có tập hợp của các hàm giúp chúng ta trong việc xử lý dữ liệu. Một trong số đó có thể kể đến như underscore, lodash, ramda... Chúng cũng được sử dụng rộng rãi trong các dự án trên github, cũng như có số lượng commit và collaborators rất lớn.

Một ví dụ như trong lodash, có đến gần 50 hàm tiện ích để xử lý dữ liệu là Object. Trong đó có cả những hàm tương tự như get ở trong ví dụ trên của tôi và hầu như bạn muốn làm gì cũng có hàm có thể đáp ứng.

Ví dụ tôi sẽ kết hợp các hàm trong lodash để giải quyết ví dụ ban đầu, hơn nữa còn thêm một điều kiện là thứ tự name được lấy ra sắp xếp theo mức độ giảm dần của age:

_.chain(users).orderBy("age", "desc").map("name").value();
Cao cấp
Hello

Bí mật ngăn xếp của Blog

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (0)

Nội dung bình luận...