Áp dụng LINQ trong javascript, chuyện nhiều người chưa biết

Như mình đã nói trong loạt bài: Học ngôn ngữ lập trình nào bây giờ?, hiện tại Javascript đang trở thành 1 trào lưu mới. Gần đây, do đang tự học Node.js nên mình tập trung nghiên cứu javascript nhiều hơn. Vì vậy, trong khoảng thời gian này mình sẽ đăng nhiều bài viết liên quan đến javascript hơn, mong các bạn theo dõi.

Như ở bài viết về LINQ, các bạn đã thấy sự mạnh mẽ và tiện dụng của LINQ trong C# (Java 8 chỉ mới cập nhật Stream API, mà vẫn còn thua LINQ nhiều lắm…). Để sử dụng 1 số hàm tương-tự-LINQ trong javascript, người ta thường dùng 1 số thư viện như: underscore, lodash, … Trong bài viết này, mình sẽ giới thiệu 1 số function (ít người biết) sẵn có trong prototype Array của javascript, cũng có tác dụng tương tự như LINQ.

advanced-javascript-3-638

Để dễ so sánh, với mỗi function trong java, mình sẽ đưa ra function tương tự trong C#. Mình sẽ dùng list dưới đây để làm ví dụ minh họa cho các function

var students = new List<Student>()
 {
 new Student() {Name = "Hoang", Age = 15},
 new Student() {Name= "Minh", Age= 5},
 new Student() {Name= "Sang", Age= 50},
 new Student() {Name= "Long", Age= 27},
 new Student() {Name= "Khoa", Age= 10},
 };
 var students=[
   {Name: 'Hoang', Age: 20},
   {Name: 'Minh', Age: 5},
   {Name: 'Sang', Age: 50},
   {Name: 'Long', Age: 27},
   {Name: 'Khoa', Age: 10},
 ];

1. filter

Trường hợp muốn lọc một số phần tử trong list, ta thường dùng hàm Where trong linq. Trong javascript, ta dùng hàm filter. Hàm này cần truyền vào 1 function để callback, với 3 tham số là: element, index, array.

 var ageLess20 = students.Where(st => st.Age < 20);
 var ageLess20 = students.filter(function(element, index, array){
      return element.Age > 22;
 });

//Nếu không quan tâm tới index hay array, ta có thể viết
 var ageLess20 = students.filter(function(st){ return st.Age > 22; });

//Ở Firefox, hiện tại javascript đã lên phiên bản ES6
//Ta có thể dùng arrow function, tương tự lambda expression
var ageLess20 = students.filter(st -> st.Age > 22);

2. every và some

Trong LINQ, ta thường dùng hàm All để kiểm tra toàn bộ phần tử thỏa mãn 1 điều kiện, hàm Any để kiểm tra nếu ít nhất 1 phần tử thỏa mãn 1 điều kiện. Trong javascript, 2 hàm ta sử dụng là every và some

//Kiểm tra toàn bộ students đều lớn hơn 5 tuổi
 bool allStudentLarger5 = students.All(st => st.Age > 5); // false
 bool anyStudentAge50 = students.Any(st => st.Age == 50); // true
 var allStudentLarger5 = students.every(function(st){ return st.Age > 5 }); // false
 var anyStudentAge50 = students.some(function(st){ return st.Age == 50 }); // true

3. forEach

Hàm này công dụng cũng như, sẽ duyệt qua 1 lần tất cả các phần từ của list, và gọi function được truyền vào.

//Duyệt từng học sinh trong list, in ra
students.ForEach(Console.WriteLine);
//Với javascript
students.forEach(console.log);

4. map

Trong LINQ, đôi khi ta cần lọc ra 1 số trường của các object trong list, ta thường sử dụng Select. Trong javascript, hàm tương tự được sử dụng là hàm map

//Lọc lấy 1 list toàn tên của học sinh
var names = students.Select(st => st.Name);
//["Hoang", "Minh", "Sang", "Long", "Khoa"]
 var names = students.map(function(st){ return st.Name });
//['Hoang', 'Minh', 'Sang', 'Long', 'Khoa']

5. reduce

Đây là hàm thay thế cho toán tử Aggregate trong LINQ. Toán tử này hơi khó giải thích, các bạn vui lòng đọc thêm ở đây: http://stackoverflow.com/questions/7105505/linq-aggregate-algorithm-explained 

6. find và findIndex (hiện tại chỉ firefox và safari)

Để tìm 1 phần tử nằm trong list, với LINQ ta thường dùng FirstOrDefault (Để lấy chính phần tử đó), hoặc FindIndex (Để tìm index của phần tử đó trong list). Lưu ý là 2 hàm này đang trong giai đoạn thử nghiệm, chỉ chạy được trên firefox và safari thôi nhé.

//Tìm học sinh có tuổi bằng 50
Student found = students.FirstOrDefault(st => st.Age == 50);
//Student Long, Age = 50

//Tìm index của học sinh đó
int index = students.FindIndex(st => st.Age == 50); //2
//Chỉ chạy được trong firefox và safari
var found = students.find(function(st){ return st.Age = 50 });

var index = students.findIndex(function(st){ return st.Age = 50 });

Nếu bạn thấy những function này không đáp ứng được như cầu, hãy chờ ở những bài sau, mình sẽ giới thiệu lo-dash, một thư viện với vô số function hỗ trợ việc duyệt và xử lý mảng. Mình đảm bảo sau khi sử dụng quen, bạn sẽ không thể code javascript mà thiếu nó (Giống như 90% developer C# bây giờ không thể sống thiếu LINQ vậy).

Kết luận: Theo ý kiến cá nhân, Javascript y hệt như con gái. Nhìn bên ngoài, có vẻ nàng là một cô nàng khá hot, nhiều người theo đuổi (1 lô 1 lốc các framework viết cho javascript). Mới quen, lại thấy nàng khá rối rắm, phức tạp, đôi khi hơi điên điên, đôi lúc lại hơi dễ dãi (Dễ dãi là vì đôi khi code js sai bét nhè chả thấy nó nói câu nào, còn về sự điên điên của js thì các bạn nên google để tìm hiểu thêm: http://webreflection.blogspot.com/2012/10/javascript-made-everyone-crazy.html). Có điều, sau khi đã quen 1 thời gian lại thấy nàng rất dễ thương, tiện dụng, cái gì cũng biết. Túm gọn lại, xin lấy tấm hình này để kết thúc bài viết.

Cái nhìn của tác giả về javascript: Xưa và nay.
Cái nhìn của tác giả về javascript: Xưa và nay.
Advertisements

3 thoughts on “Áp dụng LINQ trong javascript, chuyện nhiều người chưa biết”

  1. Ví dụ cụ thể, cách diễn đạt dễ hiểu. Rất bổ ích! Cho mình hỏi bạn đang làm công việc gì vậy? Bạn có thể recommend cho mình một số ebook hay về thuật toán (basic thôi nhá) và một số định hướng trong ngành programming dc ko?

    Like

    1. Bạn có thể đọc thử Programming Pearls hoặc Cracking the Coding Interview nhé. Về định hướng thì mình có viết 1 bài về “Con đường phát triển nghề nghiệp cho developer” trên blog đấy, bạn tìm đọc nhé 😀

      Like

  2. Chào bạn, blog của bạn rất hay, mình muốn lượm lặt một số kiến thức ở blog của bạn để đưa vào blog của mình. Vì mình chưa biết những kiến thức đó mà chưa chắc đã được dùng ngay, mình lưu lại để sau này tra cứu. Các bài viết mình hiểu và viết lại theo phong cách của mình hoặc có thể tổng hợp nhiều bài làm một, không copy nguyên. Mong bạn cho phép. Thân!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s