+1

Xử lý cấu trúc dữ liệu của JS với map/reduce

Map/reduce và spread operator là những cấu trúc rất mạnh mẽ của Javascript. Không chỉ giúp tăng khả năng đọc hiểu, tính chính xác mà chúng còn giúp đảm bảo tính bất biến của dữ liệu, bởi dữ liệu gốc ko bao giờ bị thay đổi.

Sau đây là một số cheatsheet giúp bạn viết code đẹp hơn, ngắn gọn, xúc tích hơn theo phong cách es6

Một hàm reduce đơn giản

Sử dụng reduce khi bạn muốn kết hợp data từ nhiều nguồn vào thành một thực thể.

const posts = [
  {id: 1, upVotes: 2},
  {id: 2, upVotes: 89},
  {id: 3, upVotes: 1}
];
const totalUpvotes = posts.reduce((totalUpvotes, currentPost) =>     
  totalUpvotes + currentPost.upVotes, // reducer function
  0 // initial accumulator value
);
// kết quả totalUpvotes = 92

Hàm reduce còn cung cấp thêm 2 argument khác nữa:

  1. Index của element (argument thứ 3)
  2. Cả chuỗi đầu vào (argument thứ 4) Vì vậy, một hàm reduce hoàn chỉnh trông sẽ như thế này:
collection.reduce(
  (accumulator, currentElement, currentIndex, collectionCopy) => 
    {/*function body*/},
    initialAccumulatorValue
);

Một hàm map đơn giản

Sử dụng map để xử lý những dữ liệu kiểu stream (ví dụ là array). Nó là một hàm để chuyển hóa tất cả các phần tử của một stream (array).

const integers = [1, 2, 3, 4, 6, 7];
const twoXIntegers = integers.map(i => i*2);
// twoXIntegers are now [2, 4, 6, 8, 12, 14]

Một hàm find đơn giản

Hàm này dùng để tìm ra một phần tử trong array

const posts = [
  {id: 1, title: 'Title 1'},
  {id: 2, title: 'Title 2'}
];
// find the title of post whose id is 1
const title = posts.find(p => p.id === 1).title;

Một hàm filter đơn giản

Để lọc ra những phần tử trong mảng mà thỏa mãn điều kiện của hàm.

const integers = [1, 2, 3, 4, 6, 7];
const evenIntegers = integers.filter(i => i%2 === 0);
// evenIntegers are [2, 4, 6]

Thêm một phần tử vào array

Rất hữu dụng để tạo một UI kiểu infinite scroll.

const books = ['Positioning by Trout', 'War by Green'];
const newBooks = [...books, 'HWFIF by Carnegie'];
// newBooks are now ['Positioning by Trout', 'War by Green', 'HWFIF // by Carnegie']

Tạo một mảng từ một array

Rất hữu dụng khi cần xóa một phần tử từ list, ví dụ người dùng xóa một item từ giỏ hàng.

const myId = 6;
const userIds = [1, 5, 7, 3, 6];
const allButMe = userIds.filter(id => id !== myId);
// allButMe is [1, 5, 7, 3]

Thêm một cặp key/value vào một object

const user = {name: 'Shivek Khurana'};
const updatedUser = {...user, age: 23};

Thêm một cặp key/value với giá trị linh động

const dynamicKey = 'wearsSpectacles';
const user = {name: 'Shivek Khurana'};
const updatedUser = {...user, [dynamicKey]: true};
// updatedUser is {name: 'Shivek Khurana', wearsSpectacles: true}

Tìm và thay thế một cặp key/value trong một mảng các object

const posts = [
  {id: 1, title: 'Title 1'},
  {id: 2, title: 'Title 2'}
];
const updatedPosts = posts.map(p => p.id !== 1 ?
  p : {...p, title: 'Updated Title 1'}
);
/*
updatedPosts is now 
[
  {id: 1, title: 'Updated Title 1'},
  {id: 2, title: 'Title 2'}
];
*/

Tìm một phần tử trong một mảng các object

const posts = [
  {id: 1, title: 'Title 1'},
  {id: 2, title: 'Title 2'}
];
const postInQuestion = posts.find(p => p.id === 2);
// postInQuestion now holds {id: 2, title: 'Title 2'}

Xóa một cặp key/value trong một object

const user = {name: 'Shivek Khurana', age: 23, password: 'SantaCl@use'};
const userWithoutPassword = Object.keys(user)
  .filter(key => key !== 'password')
  .map(key => ({[key]: user[key]}))
  .reduce((accumulator, current) => 
    ({...accumulator, ...current}),
    {}
  )
;
// userWithoutPassword becomes {name: 'Shivek Khurana', age: 23}

Một cách khác ngắn hơn

const user = {name: 'Shivek Khurana', age: 23, password: 'SantaCl@use'};
const userWithoutPassword = (({name, age}) => ({name, age}))(user);

Một cách khác nữa, theo tôi thì đây là cách tốt nhất:

const user = {name: 'Shivek Khurana', age: 23, password: 'SantaCl@use'};
const userWithoutPassword = Object.keys(user)
  .reduce((acc, key) => key === ‘password’ ? 
    acc : ({ …acc, [key]: user[key] }), 
    {}
  );

Cách trên còn có thể dùng để delete một mảng các key:

const user = {name: 'Shivek Khurana', age: 23, password: 'SantaCl@use'};
const userWithoutPasswordAndAge = Object.keys(user)
  .reduce((acc, key) => ['password', 'age'].indexOf(key) > -1 ? 
    acc : ({ …acc, [key]: user[key] }), 
    {}
  );

Chuyển một object sang dạng query string

const params = {color: 'red', minPrice: 8000, maxPrice: 10000};
const query = '?' + Object.keys(params)
  .map(k =>   
    encodeURIComponent(k) + '=' + encodeURIComponent(params[k])
  )
  .join('&')
;
// encodeURIComponent encodes special characters like spaces, hashes 
// query is now "color=red&minPrice=8000&maxPrice=10000"

Tìm index của một phần tử trong một mảng các object

const posts = [
  {id: 13, title: 'Title 221'},
  {id: 5, title: 'Title 102'},
  {id: 131, title: 'Title 18'},
  {id: 55, title: 'Title 234'}
];
// to find index of element with id 131
const requiredIndex = posts.map(p => p.id).indexOf(131);

Nguồn: https://codeburst.io/writing-javascript-with-map-reduce-980602ff2f2f


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí