Lọc đối tượng javascript

Một lớp lót đơn giản. WARNING. Điều này làm biến đối tượng đã được chọn thay thế vì trả lại một đối tượng mới

  • Delete the null value from a object #
  • Đọc thêm #
  • Làm thế nào để bạn loại bỏ các giá trị null khỏi một đối tượng?
  • Null có thuộc tính trong JavaScript không?
  • Làm thế nào để bạn loại bỏ các giá trị null khỏi một mảng?
  • Làm thế nào để bạn lọc một đối tượng trong JavaScript?
  • let o = Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    

    Giống như trên nhưng được viết là một chức năng

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    

    Hàm này sử dụng đệ quy để loại bỏ các mục khỏi các đối tượng lồng nhau

    function removeEmpty[obj] {
      return Object.fromEntries[
        Object.entries[obj]
          .filter[[[_, v]] => v != null]
          .map[[[k, v]] => [k, v === Object[v] ? removeEmpty[v] : v]]
      ];
    }
    

    Ví dụ về ES6/ES2015

    Một lớp lót đơn giản. WARNING. Điều này làm biến đối tượng đã được chọn thay thế vì trả lại một đối tượng mới

    Object.keys[obj].forEach[[k] => obj[k] == null && delete obj[k]];
    

    Một tuyên bố duy nhất [không thay đổi các đối tượng đã cho]

    let o = Object.keys[obj]
      .filter[[k] => obj[k] != null]
      .reduce[[a, k] => [{ ...a, [k]: obj[k] }], {}];
    

    Giống như trên nhưng được viết là một chức năng

    Hàm này sử dụng đệ quy để loại bỏ các mục khỏi các đối tượng lồng nhau

    Hàm này sử dụng đệ quy để loại bỏ các mục khỏi các đối tượng lồng nhau

    function removeEmpty[obj] {
      return Object.entries[obj]
        .filter[[[_, v]] => v != null]
        .reduce[
          [acc, [k, v]] => [{ ...acc, [k]: v === Object[v] ? removeEmpty[v] : v }],
          {}
        ];
    }
    

    Ví dụ về ES6/ES2015

    function removeEmpty[obj] {
      const newObj = {};
      Object.entries[obj].forEach[[[k, v]] => {
        if [v === Object[v]] {
          newObj[k] = removeEmpty[v];
        } else if [v != null] {
          newObj[k] = obj[k];
        }
      }];
      return newObj;
    }
    

    Một lớp lót đơn giản. WARNING. Điều này làm biến đối tượng đã được chọn thay thế vì trả lại một đối tượng mới

    Một tuyên bố duy nhất [không thay đổi các đối tượng đã cho]

    function removeEmpty[obj] {
      return Object.entries[obj]
        .filter[[[_, v]] => v != null]
        .reduce[[acc, [k, v]] => [{ ...acc, [k]: v }], {}];
    }
    
    function removeEmpty[obj] {
      return Object.keys[obj]
        .filter[function [k] {
          return obj[k] != null;
        }]
        .reduce[function [acc, k] {
          acc[k] = obj[k];
          return acc;
        }, {}];
    }
    

    Giống như chức năng trên, nhưng được viết theo cách bắt buộc [không chức năng]

    function removeEmpty[obj] {
      const newObj = {};
      Object.keys[obj].forEach[function [k] {
        if [obj[k] && typeof obj[k] === "object"] {
          newObj[k] = removeEmpty[obj[k]];
        } else if [obj[k] != null] {
          newObj[k] = obj[k];
        }
      }];
      return newObj;
    }
    

    Ví dụ về ES5/ES2009

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    0

    Delete the null value from a object #

    Để xóa tất cả các giá trị null khỏi một đối tượng. use object. Phương thức khóa [] để có được một dãy phím của đối tượng. Use method foreach[] to set over the keys. Kiểm tra xem từng giá trị có bằng null và xóa các giá trị null bằng toán tử không xóa

    Phải nói rằng 3 hàm đồ, lọc và giảm giúp ích rất nhiều. Nếu như các bạn nếu còn đang mơ hồ về chúng thì nên dành thời gian để tìm hiểu, còn tôi sẽ tóm tắt lại một chút về công dụng của 3 hàm này

    chức năng bản đồ

    Một hàm

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    16 hoạt động đối với kiểu dữ liệu là mảng, nó nhận tham số đầu vào là một hàm và trả về kết quả là một mảng với độ dài các phần tử luôn bằng gốc dữ liệu. Về cơ bản, chúng ta sử dụng bản đồ khi có mong muốn lặp lại các phần tử trong mảng để bổ sung/sửa/xoá… dữ liệu của chúng

    Hàm gọi lại của hàm map có các tham số

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    17,
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    18,
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    19 tương ứng với phần từ hiện tại, vị trí và dữ liệu của mảng

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    5
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    6

    Map function là một khai phá của Functor, nếu chưa biết về functor bạn có thể đọc bài viết của tôi tại Functor là gì?

    Ví dụ một mảng người dùng có các thông tin cơ bản như sau

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    1
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    8

    Tăng tuổi của mỗi người thêm 1

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    9
    function removeEmpty[obj] {
      return Object.fromEntries[
        Object.entries[obj]
          .filter[[[_, v]] => v != null]
          .map[[[k, v]] => [k, v === Object[v] ? removeEmpty[v] : v]]
      ];
    }
    
    0

    Ghi chú. Trường hợp này tôi đang cố ý tạo ra một đối tượng mới và trả về để tránh tham chiếu, sau khi chạy xong thì tôi có một mảng users2 hoàn toàn không tham chiếu đến người dùng

    Tôi thấy có một số người yêu thích cách viết

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    5
    function removeEmpty[obj] {
      return Object.fromEntries[
        Object.entries[obj]
          .filter[[[_, v]] => v != null]
          .map[[[k, v]] => [k, v === Object[v] ? removeEmpty[v] : v]]
      ];
    }
    
    2

    Ngắn gọn hơn rất nhiều nhưng vì thế vô tình đã làm thay đổi dữ liệu của người dùng, có thể gây ra các vấn đề về dữ liệu nếu không quản lý được việc sử dụng của người dùng ở những nơi khác. Vì vậy nếu có thể thì nên giới hạn cách viết này, thay vào đó hãy tạo ra một mảng mới

    chức năng lọc

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    80 được sử dụng để lọc ra các phần tử điều kiện đối xứng trong mảng. Đầu ra của bộ lọc luôn là một mảng có độ dài nhỏ hơn hoặc bằng dữ liệu gốc.
    Hàm callback của filter cũng giống map, nó chứa các tham số
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    17,
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    18,
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    19.

    Ví dụ tôi muốn lọc ra danh sách người dùng có tuổi >= 20

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    5
    function removeEmpty[obj] {
      return Object.fromEntries[
        Object.entries[obj]
          .filter[[[_, v]] => v != null]
          .map[[[k, v]] => [k, v === Object[v] ? removeEmpty[v] : v]]
      ];
    }
    
    8

    Bộ lọc sẽ dựa trên kết quả của lệnh gọi lại hàm trả về là đúng hoặc sai để lọc dữ liệu, nếu đúng là lấy còn sai thì không.
    Vì bộ lọc chỉ có thể lọc ra phần tử được lấy từ mảng gốc nên dữ liệu mới được tạo ra từ bộ lọc sẽ có tham chiếu đến dữ liệu gốc nên cần thận trọng.

    giảm chức năng

    Không giống với bản đồ và bộ lọc, đầu ra của giảm không được đảm bảo. Nó có thể là bất kỳ loại dữ liệu nào tùy thuộc vào mục đích.
    Reduce sẽ duyệt qua từng phần tử trong mảng, thực thi một hàm tính toán rồi trả về dữ liệu duy nhất.
    Hàm gọi lại của reduce có 4 giá trị

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    84,
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    85,
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    18,
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    19 lần lượt là tham số nhận vào ban đầu, phần tử hiện tại, vị trí phần tử hiện tại và mảng ban đầu.

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    5
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    61

    Lý thuyết thì là dài dòng nhưng tôi sẽ lấy một ví dụ đơn giản trước tiên, dưới đây là ví dụ sử dụng giảm để tính tổng các số có trong mảng

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    62
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    63

    0 là giá trị ban đầu vào lệnh cấm tương ứng với

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    84, sau đó cứ sau mỗi lần lặp nó thực hiện phép tính
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    84 +
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    85, kết quả thì gán ngược lại cho
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    84. Nên
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    84 là giá trị tích lũy sau mỗi lần lặp và nó cũng là kết quả cuối cùng giảm sẽ được trả ra

    Một ví dụ phức tạp hơn, tôi sẽ không sử dụng bộ lọc để lọc ra danh sách người dùng có tuổi >= 20, thay vào đó sẽ sử dụng giảm

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    64____165

    Với cách này, tôi có thể tránh được tham chiếu như khi sử dụng bộ lọc mặc dù nó hơi dài dòng

    Hai level when used function callback

    Ở trong các ví dụ tôi đều viết hàm gọi lại trực tiếp vào các chức năng, điều đó giúp tôi viết mã nhanh hơn nhưng đổi lại bạn sẽ có những đoạn mã dài dòng đôi khi còn gây khó khăn cho người đọc .
    Tôi tạm gọi cách viết như trên là cấp độ 1. Vì thế ở cấp 2 bạn sẽ viết như thế nào?
    Đó là cách viết bằng hàm cà ri, nếu bạn chưa biết về cà ri thì có thể tham khảo bài viết và hàm cà ri là gì? .

    Ví dụ tôi giải quyết yêu cầu ban đầu là tăng tuổi của mỗi người dùng lên 1

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    66
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    67

    Tôi tạo một hàm

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    93 có nhiệm vụ là nhận một đối tượng, tăng giá trị thuộc tính tuổi lên 1 rồi trả lại một đối tượng hoàn toàn mới. Sau đó, bản đồ nhận nó như một cuộc gọi lại để xử lý dữ liệu. Nhìn vào dòng 2, bạn có thể thấy đoạn mã tập trung vào nó đang làm gì hơn là nó đang làm như thế này…

    Cho đến bây giờ thì các yêu cầu chỉnh sửa dữ liệu hay lọc dữ liệu đơn giản mà tôi đưa ra đều được giải quyết mặc dù hơi khó thời gian viết mã một chút. Do đó, hãy đến với một yêu cầu phức tạp hơn. Tôi muốn nhóm người dùng theo city_code và sắp xếp người dùng theo thứ tự giảm dần của tuổi?

    Tôi sẽ không phát triển mã khai thác theo yêu cầu này vì mã có thể sẽ khá dài, thay vào đó tôi đưa ra cách làm như sau. Đầu tiên lấy tất cả các giá trị city_code ra rồi bộ lọc dữ liệu [duy nhất], lặp lại từng giá trị city_code để tìm những người dùng còn sót lại. End the end of the each group to sort the thứ tự người dùng trong mỗi nhóm.
    Đó là cách của tôi nghĩ ra được, nếu bạn còn cách nào khác thì hãy comment cho mọi người cùng biết nhé.

    Vì vậy, có cách nào rút gọn để giải quyết vấn đề mà không cần nhiều mã không? . Please use lodash

    Sử dụng lodash để tăng tốc độ cài đặt

    Cho những ai chưa biết thì lodash là một thư viện lý liệu dữ liệu rất nổi tiếng, với hơn 50k sao trên github thì các bạn cũng đủ biết mức độ phổ biến của thư viện này như thế nào rồi nhé.
    Go lodash thì nó là tập hợp các hàm tiện ích trong việc xử lý dữ liệu như Array hay Object, thậm chí chí là cả kiểu dữ liệu String, Number…. Nó rất là nhiều hàm, bạn có thể xem trên trang Tài liệu.

    Trong lodash có hàm

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    94 để phân nhóm và hàm
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    95 để sắp xếp dữ liệu, áp dụng nó vào giải quyết yêu cầu nhóm theo city_code trên của tôi

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    66
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    69

    Kết quả sẽ trông giống như

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    10
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    11

    Đừng quên chúng ta vẫn còn một yêu cầu nữa là sắp xếp lại dữ liệu trong mỗi nhóm theo tuổi giảm dần.
    Trong lodash có một hàm là

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    96 có thể giúp tôi sắp xếp dữ liệu theo thứ tự tăng hoặc giảm.

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    12
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    13

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    97 là hàm cho phép sửa đổi giá trị của từng thuộc tính có trong đối tượng. Ở đây tôi sử dụng
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    97 để sắp xếp dữ liệu trong mỗi nhóm

    Lodash còn hỗ trợ cách viết chuỗi hàm, nghĩa là một chuỗi các hàm nối liền nhau. Đầu ra của hàm này sẽ là đầu vào của hàm kia. Có thể nói nó giống như hàm soạn thảo/ống dẫn mà tôi đã có bài viết ở Triển khai mã hiệu quả hơn so với hàm soạn thảo & ống dẫn trong Javascript

    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    9
    function removeEmpty[obj] {
      return Object.fromEntries[Object.entries[obj].filter[[[_, v]] => v != null]];
    }
    
    15

    Hai cách đều giải quyết được vấn đề, tuy nhiên cách 1 thì tập trung vào làm như thế nào còn cách 2 thì đang làm gì hơn

    Chủ Đề