Hôm nay tôi chia sẻ với anh em cách so sánh giữa 2 mảng một cách nhanh nhất mà không dùng tới vòng lặp for, while. Nhưng trước khi vào chia sẻ tôi khẳng định thế này. Nếu không dùng for, while thì chắc chắn phải dùng một cái khác thay thế rồi. Và cái thay thế cho for, while ở đây chính là Linq

Tôi sẽ thực hiện việc so sánh giữa 2 mảng bằng C#Javascript

1. So sánh giữa 2 mảng bằng ngôn ngữ C#
Tạo ngẫu nhiên 2 dãy số
Tạo 2 dãy số
  •  
  • Chỉ có ở mảng 1
  •  
  • Chỉ có ở mảng 2
  •  
  • Xuất hiện ở cả 2 mảng

Để thực hiện so sánh 2 mảng tôi đã viết một hàm Extension mở rộng cho IEnumerable như sau

public static IEnumerable<T1> FindNewItems<T1, T2, T>(this IEnumerable<T1> list1, IEnumerable<T2> list2, Func<T1, T> ex1, Func<T2, T> ex2)
{
    return (from item1 in list1
            join item2 in list2 on ex1(item1) equals ex2(item2) into left
            from itemLeft in left.DefaultIfEmpty()
            select new { item1, itemLeft }).Where(o => Equals(o.itemLeft, default(T2))).Select(o => o.item1);
}

Tên hàm nghĩa là từ list1 sẽ tìm tới các phần tử mới mà list2 không có. Nó tương tự như câu lệnh LEFT OUTER JOIN trong Sql

Cách sử dụng trong mô phỏng bằng C#

var result1 = arr1.FindNewItems(arr2, a1 => a1, a2 => a2).ToList(),
var result2 = arr2.FindNewItems(arr1, a2 => a2, a1 => a1).ToList(),
var result0 = arr1.Join(arr2, a1 => a1, a2 => a2, (a1, a2) => a1).ToList()

Với result1 gồm phần tử chỉ xuất hiện ở mảng 1, result2 gồm chỉ phần tử xuất hiện ở mảng 2 còn result0 tôi sử dụng hàm Join Linq Object trong C# để thực hiện tìm 2 phần tử giống nhau ở 2 mảng. Như vậy chỉ với 3 dòng lệnh là tôi đã có thể so sánh nhanh chóng 2 mảng với nhau.

2. So sánh giữa 2 mảng bằng ngôn ngữ javascript
Tạo ngẫu nhiên 2 dãy số
Tạo 2 dãy số
  •  
  • Chỉ có ở mảng 1
  •  
  • Chỉ có ở mảng 2
  •  
  • Xuất hiện ở cả 2 mảng

Cũng tương tự như so sánh bằng C# thì ở Javascript tôi cũng sẽ dùng thư viện linq.js để thực hiện. Các bạn có thể đọc lại bài viết Thư viện Linq.js trong javascript mà tôi đã chia sẻ.

javascript tôi cũng viết một hàm mở rộng cho Enumerable như sau

Enumerable.prototype.FindNewItems = function (list2, acc1, acc2)
{            
    return this.GroupJoin(list2, item1 => acc1(item1), item2 => acc2(item2), function (item1, list2Items) { return { item1, list2Items };  })
        .Where(a => a.list2Items.Count() == 0)
        .Select(a => a.item1);
}

Tên hàm vẫn có nghĩa là list1 sẽ tìm tới các phần tử mới mà list2 không có. Rất giống với hàm tôi viết trong C# đúng không nhỉ.

Cách sử dụng trong mô phỏng bằng Javascript

var result1 = Enumerable.From(array1).FindNewItems(array2, item1 => item1, item2 => item2).ToArray();
var result2 = Enumerable.From(array2).FindNewItems(array1, item2 => item2, item1 => item1).ToArray();
var result0 = Enumerable.From(array1).Join(array2, item1 => item1, item2 => item2, (item1, item2) => item1).ToArray();

Không khác gì với C#, tôi cũng chỉ mất có 3 dòng lệnh để so sánh 2 mảng bằng Javascript

Trong thực tế phần mềm của tôi rất hay dùng tới việc so sánh này. Cụ thể là tôi thường phải lưu trữ một danh sách bản ghi vào DataBase. Ví dụ như danh sách chi tiết các sản phẩm của một đơn hàng. Lúc lưu trữ tôi sẽ so sánh danh sách chi tiết khách hàng đang nhập ở giao diện với danh sách đã có trong DataBase. Từ đó sẽ tìm ra bản ghi nào cần: 

  • 1. Thêm mới: Khách hàng thêm bản ghi trên giao diện. Như vậy so với trong DataBase là những bản ghi mới.
  • 2. Xóa: Khách hàng xóa bỏ bản ghi. Như vậy so với DataBase là đã bị gỡ bỏ
  • 3. Cập nhật: Chỉ việc Join để tìm bản ghi cần sửa

Đây chính là màn hình đơn hàng trong phần mềm của tôi

Như đã nói ở tiêu đề là tôi hoàn toàn không dùng vòng lặp. Nhưng mà tôi chắc chắn rằng sẽ có các bạn bình luận rằng ở trong cái Linq thì lại chả có cả đống vòng for, while smiley. Các bạn phải đọc rõ tiêu đề là tôi không dùng for, while còn Linq nó dùng thì tôi ko quan tâm. Cũng giống như tôi chia sẻ bài viết Code mô phỏng đèn tín hiệu giao thông bằng javascript là tôi không dùng if, else mà các bạn cứ vào comment là thư viện tôi dùng thì lại chả có if blush

Nói vậy thôi, anh em comment thế nào cũng được. Miễn là chúng ta cùng chia sẻ và học hỏi thôi. Chúc các bạn cuối tuần vui vẻ

Sơn 20