Hướng dẫn dùng one-line JavaScript

Nội dung bài viết

Video học lập trình mỗi ngày

JavaScript utilities - Anh em dev nào cũng có một file này, như một bí kíp vậy, được sử dụng từ project này qua project khác. Trong bài post này, hãy để tipjs share thêm một số bí kíp khác giúp chúng ta hoàn thành file utilities js một cách hoàn hảo hơn, chỉ mới một line code!

Học được gì sau bài viết này

  • Viết code một cách sạch sẽ
  • Tham khảo một số code mẫu
  • Mẹo này có thể chưa tốt đối với một số trường hợp

Dưới đây là một số code mẫu chỉ giải quyết trong vòng một line code. Có thể nó không phù hợp với tất cả ngữ cảnh hay tình huống, nhưng nó khá tốt cho những ai muốn được học hỏi thêm về khả năng viết code của mình. Cải thiện được nếu bạn có thể. Nhưng tipjs vẫn có một câu nói thế này:

"Một người code giỏi không có nghĩa là code của họ chạy ổn và hiệu suất cao. Mà trong đó còn có thể truyền đạt lại cho người khác một cách dễ dàng".

Vì lẽ đó nên cẩn thận, bởi người sau có thể không hiểu code của bạn, cho dù là ngắn nhất.

Notes: Một số thủ thuật làm việc với Array JavaScript

Check if all items in an array are equal

const areEqual = arr => arr.length > 0 && arr.every(item => item === arr[0]);
// areEqual([1, 2, 3, 4]) === false
// areEqual(['hello', 'hello', 'hello']) === true

Check if an object is an array

const isArray = obj => Array.isArray(obj);

Convert an array of strings to numbers

const toNumbers = arr => arr.map(Number);

// Or
const toNumbers = arr => arr.map(x => +x);

// toNumbers(['2', '3', '4']) returns [2, 3, 4]

Create an array of cumulative sum

const accumulate = arr => arr.map((sum => value => sum += value)(0));

// Or
const accumulate = arr => arr.reduce((a, b, i) => i === 0 ? [b] : [...a, b + a[i - 1]], []);

// Or
const accumulate = arr => arr.reduce((a, b, i) => i === 0 ? [b] : [...a, b + a[i - 1]], 0);

/*
accumulate([1, 2, 3, 4]) === [1, 3, 6, 10]
// 1             = 1
// 1 + 2         = 3
// 1 + 2 + 3     = 6
// 1 + 2 + 3 + 4 = 10
*/

Create an array of numbers in the given range

const range = (min, max) => [...Array(max - min + 1).keys()].map(i => i + min);
// range(5, 10) === [5, 6, 7, 8, 9, 10]

Empty an array

const empty = arr => arr.length = 0;

// Or
arr = [];

Find the length of the longest string in an array

const findLongest = words => Math.max(...(words.map(el => el.length)));
// findLongest(['always','look','on','the','bright','side','of','life']) === 6;

Find the maximum item of an array

const max = arr => Math.max(...arr);

Find the minimum item of an array

const min = arr => Math.min(...arr);

Flatten an array

const flat = arr => arr.reduce((a, b) => Array.isArray(b) ? [...a, ...flat(b)] : [...a, b], []);

// Or
// See the browser compatibility at https://caniuse.com/#feat=array-flat
const flat = arr => arr.flat();

// flat(['cat', ['lion', 'tiger']]) returns ['cat', 'lion', 'tiger']

Get a random item from an array

const randomItem = arr => arr[(Math.random() * arr.length) | 0];

Get the average of an array

const average = arr => arr.reduce((a, b) => a + b, 0) / arr.length;

Get the sum of array of numbers

const sum = arr => arr.reduce((a, b) => a + b, 0);

Get the unique values of an array

const unique = arr => [...new Set(arr)];

// Or
const unique = arr => arr.filter((el, i, array) => array.indexOf(el) === i);

Merge two arrays

// Merge but don't remove the duplications
const merge = (a, b) => a.concat(b);
// Or
const merge = (a, b) => [...a, ...b];

// Merge and remove the duplications
const merge = [...new Set(a.concat(b))];
// Or
const merge = [...new Set([...a, ...b])];

DATETIME - single line of code

Còn nữa... Resource:  reddit 

One-line solution, hay được gọi là đoạn code chỉ đúng 1 dòng nhằm giải quyết một vấn đề nào đó, cùng mình tìm hiểu vài solution đơn giản như đang giỡn qua vài ví dụ “khá là thực tế” trong bài viết này nhé.

Hướng dẫn dùng one-line JavaScript

Kiểm tra mảng có chứa phần tử trùng nhau

Thằng em fresher vừa vào team và được giao chức năng code random bộ câu hỏi trong ngân hàng đề vài nghìn câu, là một tester, bạn muốn thử chạy random vài trăm bộ đề và muốn kiểm tra xem có xảy ra trường hợp có câu hỏi nào bị trùng nhau trong bất kì bộ đề được tạo ra hay không.

Dĩ nhiên, yêu cầu chỉ cần bạn kiểm tra mảng danh sách câu hỏi (mảng chỉ chứa số nguyên) có bị trùng lặp phần tử nào hay không, nếu trùng thì cứ dí bug vào em nó thôi.

Bài toán được đơn giản hóa như sau

Input: mảng số nguyên không rỗng.

Output: kiểm tra mảng input có chứa phần tử nào bị trùng nhau hay không.

Theo cách tiếp cận thông thường, bạn sẽ thường đếm, hoặc đánh dấu từng phần tử trong mảng, nếu số lần xuất hiện (hoặc bị đánh dấu) vượt quá 1 lần thì kết luận mảng sẽ chứa phần tử trùng nhau.

Nhưng chiêu trò hơn một chút, bạn đã thử cân nhắc việc sử dụng cấu trúc dữ liệu không chứa phần tử trùng nhau như dưới đây chưa?

// Javascript solution
function hasDuplicates(arr) {
    return (new Set(arr)).size !== arr.length;
}


// Java solution
public boolean hasDuplicates(List arr) {
    return new HashSet(arr).size() != arr.size();
}

Dĩ nhiên, trick này cũng được sử dụng để kiểm tra mảng không chứa phần tử nào khác nhau, bạn hãy thử tìm solution cho trường hợp này nhé.

Tìm số ngày trong tháng

Input: tháng và năm hợp lệ (đã có hàm kiểm tra năm nhuận).

Output: số ngày trong tháng đó.

Có lẽ đây không còn là bài toán quá xa lạ với các lập trình viên, tuy nhiên logic thường được dạy ở trường và một số solution mẫu sẽ sử dụng switch-case.

Nếu một số trường hợp kết quả được xét lần lượt theo chuỗi các giá trị liên tiếp, ví dụ trong trường hợp này là tháng từ 1 đến 12, bạn hãy thử cân nhắc sử dụng cấu trúc mảng xem sao?

// Javascript solution
function countDayOfMonth(month, year) {
    return [31, isLeapYear(year) ? 29 : 28, 
    31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1];
}


// Java solution
public int countDayOfMonth(int month, int year) {
    return Arrays.asList(31, isLeapYear(year) ? 29 : 28,
    31, 30, 31, 30, 31, 31, 30, 31, 30, 31].get(month - 1);
}

Nếu các chuỗi giá trị cần xét không liên tiếp, hoặc cần xét các giá trị ngoài kiểu dữ liệu số, bạn có thể áp dụng dạng object (trong JS) hoặc HashMap (trong Java) theo cặp key-value cũng là một cách tiếp cận khá phổ biến.

Trick này có thể sử dụng để tìm tên của thứ trong tuần (thứ hai, thứ ba…), hoặc tìm tên năm Âm Lịch của một năm, bạn có thể tham khảo công thức tìm Can – Chi tại đây nhé.

Kiểm tra giá trị là một trong các giá trị

Bạn kinh doanh nhà hàng Pizza với nhiều loại trên thế giới, hôm nay bạn chạy chiến dịch nhằm đẩy mạnh 5 doanh số loại pizza: hải sản, phô mai, cá hồi, rau củ và bò, nếu khách đặt mua một trong số các loại pizza này sẽ được một phiếu giảm giá siêu to khổng lồ trên dưới 1 tỉ chẳng hạn.

Input: Loại pizza khách đã đặt

Output: Kiểm tra loại pizza có thuộc trong chương trình khuyến mãi.

Theo cách tiếp cận dễ dàng nhất, chỉ cần xét giá trị của input cùng với các câu điều kiện or và so sánh bằng, ta đã có thể giải quyết bài toán, tuy nhiên có thể làm mất “thẩm mĩ” khi đoạn code so sánh bằng sẽ bị lặp lại khá nhiều và dài dòng.

Cách tiếp cận bài toán trên có thể phát biểu như sau: kiểm tra xem các loại pizza đang khuyến mãi có chứa loại pizza của khách đã đặt hay không, dĩ nhiên, đoạn code sẽ trở nên trong sáng hơn nhiều:

// Javascript solution
function isDiscountType(type) {
    return ['seafood', 'cheese', 'salmon', 'vegie','beef'].includes(type);
}


// Java solution
public boolean isDiscountType(String type) {
    return Arrays.asList("seafood", "cheese", "salmon", "vegie", "beef").contains(type);
}

Trick này có thể sử dụng trong bài toán kiểm tra định dạng file upload có thuộc các định dạng được hỗ trợ hay không – bài toán khá phổ biến trong lập trình web.

Trên đây là một số one-trick solution mà mình lân la tìm hiểu được trong quá trình tìm tòi lập trình, nếu bạn có trick thú vị nào khác, có thể chia sẻ cùng mình nhé! =)