Lodash 文字列ユーティリティ早見表:case 変換・パディング・トリムの極意
JavaScript で文字列操作を行う際、Lodash のユーティリティ関数を活用することで、コードの可読性と保守性が飛躍的に向上します。今回は、実務で頻繁に使用される case 変換・パディング・トリム処理に焦点を当て、実践的な使い方をご紹介しますね。
この記事では、各関数の使用方法を早見表で整理し、具体的なコード例とともに解説していきます。
早見表
case 変換関数一覧
| # | 関数名 | 変換結果の形式 | 使用例入力 | 使用例出力 | 主な用途 |
|---|---|---|---|---|---|
| 1 | camelCase | キャメルケース | "hello world" | "helloWorld" | JavaScript 変数名、プロパティ名 |
| 2 | kebabCase | ケバブケース | "hello world" | "hello-world" | URL スラッグ、CSS クラス名 |
| 3 | snakeCase | スネークケース | "hello world" | "hello_world" | データベースカラム名、定数名 |
| 4 | startCase | スタートケース | "hello world" | "Hello World" | タイトル表示、見出し |
| 5 | lowerCase | 小文字 + スペース区切り | "helloWorld" | "hello world" | 検索用正規化テキスト |
| 6 | upperCase | 大文字 + スペース区切り | "helloWorld" | "HELLO WORLD" | 強調表示テキスト |
| 7 | capitalize | 先頭文字のみ大文字 | "hello world" | "Hello world" | 文章の先頭、単語の先頭 |
| 8 | lowerFirst | 先頭文字のみ小文字 | "Hello World" | "hello World" | プライベートメソッド名 |
| 9 | upperFirst | 先頭文字のみ大文字 | "hello world" | "Hello world" | クラス名、コンストラクタ名 |
パディング・トリム関数一覧
| # | 関数名 | 機能 | 使用例入力 | 使用例出力 | 主な用途 |
|---|---|---|---|---|---|
| 1 | pad | 両側パディング | "abc", 8 | " abc " | センタリング表示 |
| 2 | padStart | 左側パディング | "5", 3, "0" | "005" | ゼロ埋め、桁揃え |
| 3 | padEnd | 右側パディング | "abc", 6, "_" | "abc___" | 固定長フォーマット |
| 4 | trim | 両端の空白削除 | " hello " | "hello" | ユーザー入力の正規化 |
| 5 | trimStart | 先頭の空白削除 | " hello" | "hello" | インデント除去 |
| 6 | trimEnd | 末尾の空白削除 | "hello " | "hello" | 行末スペース除去 |
| 7 | truncate | 文字列の切り詰め | "hello world", {length: 8} | "hello..." | 長文の省略表示 |
| 8 | repeat | 文字列の繰り返し | "*", 5 | "*****" | 区切り線、パターン生成 |
背景
JavaScript における文字列処理の課題
JavaScript では文字列操作が標準で提供されていますが、実務で必要となる高度な処理を実装するには、多くのコードを書く必要があります。特に、命名規則の統一やフォーマット処理は、プロジェクト全体の一貫性を保つ上で非常に重要ですね。
以下の図は、Lodash を活用することで文字列処理がどのように効率化されるかを示しています。
mermaidflowchart TB
input["生の文字列データ"]
subgraph traditional["従来の方法"]
manual1["手動で split/join"]
manual2["正規表現パターン記述"]
manual3["複数行のコード"]
manual4["エッジケース処理"]
end
subgraph lodash["Lodash による方法"]
util1["camelCase() など<br/>単一関数呼び出し"]
util2["内部で最適化済み"]
util3["1行で完結"]
end
input --> traditional
input --> lodash
traditional --> output1["変換結果<br/>(コード量多・保守性低)"]
lodash --> output2["変換結果<br/>(コード量少・保守性高)"]
図で理解できる要点:
- 従来の方法では複数のステップと正規表現が必要
- Lodash では単一関数で同じ結果を得られる
- コードの可読性と保守性が大幅に向上
Lodash が提供する価値
Lodash は、文字列処理において以下のような価値を提供します。
まず第一に、一貫性のある API を提供してくれます。命名規則の変換や文字列の整形が、直感的な関数名で実行できるのです。
次に、エッジケースへの対応 が組み込まれています。空文字列や null、undefined などの特殊なケースも適切に処理されるため、安心して利用できますね。
最後に、パフォーマンスの最適化 が施されています。内部実装が効率的に設計されているため、大量のデータ処理でも高速に動作します。
mermaidflowchart LR
developer["開発者"] -->|入力文字列| lodash["Lodash<br/>ユーティリティ"]
subgraph features["Lodash の特徴"]
api["一貫性のある API"]
edge["エッジケース対応"]
perf["パフォーマンス最適化"]
end
lodash --> features
features --> result["期待通りの変換結果"]
result --> app["アプリケーション"]
課題
実務で直面する文字列処理の問題
実際の開発現場では、以下のような文字列処理の課題に直面することが多いです。
命名規則の不統一
API レスポンスのキー名が snake_case なのに対し、フロントエンドでは camelCase を使用する場合、データの変換処理が必要になります。この変換を手動で実装すると、コードが複雑化し、バグの温床となってしまうでしょう。
ユーザー入力の正規化
フォーム入力では、ユーザーが意図せず入力した前後の空白や、全角スペースの混在などが問題になります。これらを適切に処理しないと、検索機能やバリデーションが正しく動作しません。
表示用フォーマット
数値のゼロ埋めや、長文の省略表示など、UI に表示する際のフォーマット処理は多岐にわたります。それぞれを独自実装すると、コードの重複が発生してしまいますね。
以下の図は、これらの課題がどのように関連しているかを示しています。
mermaidflowchart TD
issues["文字列処理の課題"]
issues --> naming["命名規則の不統一"]
issues --> input["ユーザー入力の問題"]
issues --> format["表示フォーマット"]
naming --> api["API: snake_case"]
naming --> frontend["Frontend: camelCase"]
input --> space["前後の空白"]
input --> fullwidth["全角スペース混在"]
format --> zero["ゼロ埋め"]
format --> ellipsis["長文省略"]
api --> convert["変換処理が必要"]
frontend --> convert
space --> normalize["正規化処理が必要"]
fullwidth --> normalize
zero --> formatter["フォーマッター必要"]
ellipsis --> formatter
図で理解できる要点:
- 3 つの主要課題が異なる処理を要求する
- それぞれに専用の処理関数が必要
- Lodash がこれらすべてに対応する関数を提供
パフォーマンスとメンテナンス性のトレードオフ
自前で文字列処理を実装する場合、パフォーマンスを重視すると複雑なコードになり、メンテナンス性が低下します。逆に、可読性を重視すると処理速度が犠牲になることがあるのです。
Lodash を使用することで、このトレードオフから解放され、パフォーマンスと可読性の両方を手に入れることができます。
解決策
Lodash による統一的なアプローチ
Lodash の文字列ユーティリティを活用することで、先述の課題をエレガントに解決できます。ここでは、主要な 3 つのカテゴリ(case 変換・パディング・トリム)について、具体的な解決方法をご紹介しますね。
以下の図は、Lodash の文字列関数がどのように分類され、それぞれがどのような役割を果たすかを示しています。
mermaidflowchart TB
lodash["Lodash 文字列ユーティリティ"]
lodash --> case["Case 変換系"]
lodash --> padding["パディング系"]
lodash --> trim["トリム・整形系"]
case --> camel["camelCase<br/>kebabCase<br/>snakeCase"]
case --> capitalize_group["capitalize<br/>upperFirst<br/>lowerFirst"]
case --> start["startCase<br/>lowerCase<br/>upperCase"]
padding --> pad_group["pad<br/>padStart<br/>padEnd"]
padding --> repeat_func["repeat"]
trim --> trim_group["trim<br/>trimStart<br/>trimEnd"]
trim --> truncate_func["truncate"]
camel --> use1["変数名・プロパティ"]
pad_group --> use2["固定長フォーマット"]
trim_group --> use3["入力値正規化"]
図で理解できる要点:
- 3 つの主要カテゴリに関数が分類される
- 各カテゴリ内で複数の関数が用途別に用意されている
- 用途に応じて適切な関数を選択できる
インストールと基本セットアップ
まず、Lodash をプロジェクトに導入しましょう。Yarn を使用してインストールします。
bashyarn add lodash
TypeScript を使用する場合は、型定義ファイルも追加します。
bashyarn add -D @types/lodash
基本的なインポート方法は 2 つあります。必要な関数のみをインポートする方法と、ライブラリ全体をインポートする方法です。
javascript// 必要な関数のみをインポート(推奨:バンドルサイズ削減)
import { camelCase, snakeCase, trim } from 'lodash';
javascript// ライブラリ全体をインポート
import _ from 'lodash';
// 使用例
const result = _.camelCase('hello world');
個別インポートを使用すると、Tree Shaking によって未使用の関数がバンドルから除外され、最終的なファイルサイズが削減されます。本記事では、個別インポートの方式で解説を進めていきますね。
TypeScript での型定義活用
TypeScript プロジェクトでは、Lodash の型定義を活用することで、型安全性が向上します。
typescriptimport { camelCase } from 'lodash';
// 型推論が効く
const userName: string = camelCase('user name'); // "userName"
typescript// オプション引数も型チェックされる
import { truncate } from 'lodash';
const text = 'This is a long text';
const shortened = truncate(text, {
length: 10, // 数値のみ
omission: '...', // 文字列のみ
separator: ' ', // 文字列または正規表現
});
型定義により、関数の引数や戻り値の型が明確になり、IDE の補完機能も活用できるため、開発効率が大幅に向上するでしょう。
具体例
Case 変換の実践例
命名規則の変換は、API 連携やコーディング規約の統一において非常に重要です。ここでは、各 case 変換関数の具体的な使用例をご紹介します。
camelCase プロパティ名への変換
API から取得したデータのキー名を JavaScript の命名規則に変換する例です。
javascriptimport { camelCase } from 'lodash';
// API レスポンスのキー名を変換
const apiKey = 'user_profile_image';
const jsProperty = camelCase(apiKey);
console.log(jsProperty); // "userProfileImage"
複数のキーを一括変換する関数を作成することもできます。
javascriptimport { camelCase } from 'lodash';
// オブジェクトのキーを一括変換する関数
function convertKeysToCamelCase(obj) {
const result = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[camelCase(key)] = obj[key];
}
}
return result;
}
javascript// 使用例
const apiResponse = {
user_name: 'John Doe',
user_age: 30,
profile_image_url: 'https://example.com/image.jpg',
};
const convertedData = convertKeysToCamelCase(apiResponse);
console.log(convertedData);
// {
// userName: 'John Doe',
// userAge: 30,
// profileImageUrl: 'https://example.com/image.jpg'
// }
この関数により、API レスポンス全体を一度に変換できるため、フロントエンドでの扱いが非常に楽になりますね。
kebabCase スラッグと CSS クラス名
ブログ記事のタイトルから URL スラッグを生成する例です。
javascriptimport { kebabCase } from 'lodash';
// 記事タイトルから URL スラッグを生成
const articleTitle = 'Lodash 文字列ユーティリティ早見表';
const urlSlug = kebabCase(articleTitle);
console.log(urlSlug);
// "lodash-文字列-ユーティリティ-早見表"
javascript// 英数字のみの場合
const englishTitle = 'Getting Started with Lodash';
const englishSlug = kebabCase(englishTitle);
console.log(englishSlug);
// "getting-started-with-lodash"
CSS の BEM 記法でクラス名を生成する例も見てみましょう。
javascriptimport { kebabCase } from 'lodash';
// BEM 記法のクラス名生成
function generateBemClass(block, element, modifier) {
const blockName = kebabCase(block);
const elementName = element
? `__${kebabCase(element)}`
: '';
const modifierName = modifier
? `--${kebabCase(modifier)}`
: '';
return `${blockName}${elementName}${modifierName}`;
}
javascript// 使用例
const className1 = generateBemClass(
'UserProfile',
'Avatar',
'Large'
);
console.log(className1); // "user-profile__avatar--large"
const className2 = generateBemClass(
'Navigation Menu',
'Item'
);
console.log(className2); // "navigation-menu__item"
kebabCase を使用することで、スペースや大文字を含む文字列も、自動的に URL や CSS に適した形式に変換されます。
snakeCase:データベースカラム名と定数
データベースのカラム名は、多くの場合 snake_case で記述されます。
javascriptimport { snakeCase } from 'lodash';
// JavaScript のプロパティ名をDB カラム名に変換
const jsProperty = 'createdAt';
const dbColumn = snakeCase(jsProperty);
console.log(dbColumn); // "created_at"
ORM のマッピング設定を自動生成する例です。
javascriptimport { snakeCase } from 'lodash';
// フィールド定義からDB マッピングを生成
const userFields = [
'userId',
'userName',
'emailAddress',
'createdAt',
'updatedAt',
];
const dbMapping = userFields.reduce((acc, field) => {
acc[field] = snakeCase(field);
return acc;
}, {});
console.log(dbMapping);
// {
// userId: 'user_id',
// userName: 'user_name',
// emailAddress: 'email_address',
// createdAt: 'created_at',
// updatedAt: 'updated_at'
// }
環境変数や定数名の生成にも活用できます。
javascriptimport { snakeCase } from 'lodash';
// 設定項目から環境変数名を生成(大文字化も含む)
function generateEnvVarName(configKey) {
return snakeCase(configKey).toUpperCase();
}
const apiEndpoint = generateEnvVarName('apiEndpointUrl');
console.log(apiEndpoint); // "API_ENDPOINT_URL"
const dbHost = generateEnvVarName('databaseHostName');
console.log(dbHost); // "DATABASE_HOST_NAME"
startCase:タイトルと見出しの整形
ユーザーに表示するタイトルやラベルを整形する際に便利です。
javascriptimport { startCase } from 'lodash';
// プロパティ名から表示ラベルを生成
const propertyName = 'firstName';
const displayLabel = startCase(propertyName);
console.log(displayLabel); // "First Name"
javascript// 複数の形式に対応
const examples = [
'user_name', // "User Name"
'emailAddress', // "Email Address"
'profile-image', // "Profile Image"
'PRODUCT_ID', // "PRODUCT ID"
];
examples.forEach((example) => {
console.log(`${example} → ${startCase(example)}`);
});
フォームのフィールドラベルを自動生成する実用的な例です。
javascriptimport { startCase } from 'lodash';
// フォームフィールド定義
const formFields = {
userName: '',
emailAddress: '',
phoneNumber: '',
companyName: '',
};
// ラベルを自動生成
function generateFormLabels(fields) {
const labels = {};
for (const field in fields) {
labels[field] = startCase(field);
}
return labels;
}
const labels = generateFormLabels(formFields);
console.log(labels);
// {
// userName: 'User Name',
// emailAddress: 'Email Address',
// phoneNumber: 'Phone Number',
// companyName: 'Company Name'
// }
この方法により、フィールド名とラベルを別々に管理する必要がなくなり、メンテナンス性が向上しますね。
capitalize、lowerFirst、upperFirst:細かな制御
先頭文字のみを制御する関数も、特定の場面で非常に役立ちます。
javascriptimport { capitalize, lowerFirst, upperFirst } from 'lodash';
const text = 'hello world';
console.log(capitalize(text)); // "Hello world"
console.log(upperFirst(text)); // "Hello world" (capitalize と同じ)
console.log(lowerFirst('Hello World')); // "hello World"
文章の先頭を大文字にする実用例です。
javascriptimport { capitalize } from 'lodash';
// ユーザーのコメントを整形
function formatUserComment(comment) {
// 前後の空白を削除してから先頭を大文字化
const trimmed = comment.trim();
return capitalize(trimmed);
}
const rawComment = ' this is a great article!';
const formatted = formatUserComment(rawComment);
console.log(formatted); // "This is a great article!"
クラス名やコンストラクタ名を生成する例も見てみましょう。
javascriptimport { upperFirst, camelCase } from 'lodash';
// テーブル名からモデルクラス名を生成
function generateModelClassName(tableName) {
// snake_case をcamelCase に変換してから先頭を大文字化
return upperFirst(camelCase(tableName));
}
console.log(generateModelClassName('user_profiles')); // "UserProfiles"
console.log(generateModelClassName('product_categories')); // "ProductCategories"
javascriptimport { lowerFirst, camelCase } from 'lodash';
// プライベートメソッド名を生成
function generatePrivateMethodName(methodName) {
// 先頭を小文字化してプライベート感を出す
return `_${lowerFirst(camelCase(methodName))}`;
}
console.log(generatePrivateMethodName('Calculate Total')); // "_calculateTotal"
console.log(generatePrivateMethodName('validate_input')); // "_validateInput"
パディングの実践例
パディング関数は、文字列を指定の長さに揃える際に使用します。数値のゼロ埋めや、テーブル表示の整形に便利ですね。
padStart:ゼロ埋めと桁揃え
数値を指定桁数でゼロ埋めする最も一般的な使用例です。
javascriptimport { padStart } from 'lodash';
// ID を5桁のゼロ埋めで表示
const userId = '123';
const formattedId = padStart(userId, 5, '0');
console.log(formattedId); // "00123"
javascript// 複数のID を一括変換
const userIds = ['1', '42', '999', '1234', '56789'];
const formattedIds = userIds.map((id) =>
padStart(id, 5, '0')
);
console.log(formattedIds);
// ["00001", "00042", "00999", "01234", "56789"]
時刻表示のフォーマットにも活用できます。
javascriptimport { padStart } from 'lodash';
// 時刻を HH:MM:SS 形式で表示
function formatTime(hours, minutes, seconds) {
const h = padStart(String(hours), 2, '0');
const m = padStart(String(minutes), 2, '0');
const s = padStart(String(seconds), 2, '0');
return `${h}:${m}:${s}`;
}
console.log(formatTime(9, 5, 3)); // "09:05:03"
console.log(formatTime(14, 30, 45)); // "14:30:45"
ファイル名の連番生成にも便利です。
javascriptimport { padStart } from 'lodash';
// 連番ファイル名を生成
function generateFileName(prefix, index, extension) {
const paddedIndex = padStart(String(index), 4, '0');
return `${prefix}_${paddedIndex}.${extension}`;
}
// 使用例:画像ファイルの連番
for (let i = 1; i <= 5; i++) {
console.log(generateFileName('image', i, 'jpg'));
}
// image_0001.jpg
// image_0002.jpg
// image_0003.jpg
// image_0004.jpg
// image_0005.jpg
padEnd:固定長フォーマット
右側をパディングする padEnd は、テーブル表示や固定長データの生成に使用します。
javascriptimport { padEnd } from 'lodash';
// 商品名を20文字に揃える
const productName = 'Laptop';
const paddedName = padEnd(productName, 20, '.');
console.log(paddedName); // "Laptop.............."
テーブル形式で複数項目を表示する例です。
javascriptimport { padEnd } from 'lodash';
// 商品リストをテーブル形式で表示
const products = [
{ name: 'Laptop', price: 1200 },
{ name: 'Mouse', price: 25 },
{ name: 'Keyboard', price: 80 },
{ name: 'Monitor', price: 350 },
];
console.log(padEnd('Product', 20) + 'Price');
console.log('-'.repeat(30));
products.forEach((product) => {
const nameColumn = padEnd(product.name, 20);
const priceColumn = `$${product.price}`;
console.log(nameColumn + priceColumn);
});
// 出力:
// Product Price
// ------------------------------
// Laptop $1200
// Mouse $25
// Keyboard $80
// Monitor $350
CSV ファイルの固定長データを生成する例も見てみましょう。
javascriptimport { padEnd } from 'lodash';
// 固定長CSVレコードを生成
function createFixedLengthRecord(data) {
return [
padEnd(data.id, 10),
padEnd(data.name, 30),
padEnd(data.email, 40),
].join('');
}
const users = [
{
id: '001',
name: 'John Doe',
email: 'john@example.com',
},
{
id: '002',
name: 'Jane Smith',
email: 'jane@example.com',
},
];
users.forEach((user) => {
console.log(createFixedLengthRecord(user));
});
// 001 John Doe john@example.com
// 002 Jane Smith jane@example.com
pad:中央寄せ表示
両側をパディングする pad は、タイトルのセンタリング表示に便利です。
javascriptimport { pad } from 'lodash';
// タイトルを中央寄せで表示
const title = 'Report';
const centeredTitle = pad(title, 20, '=');
console.log(centeredTitle); // "=======Report======="
javascript// ヘッダーセクションを作成
function createHeader(title, width = 50) {
const border = '='.repeat(width);
const centeredTitle = pad(` ${title} `, width, '=');
return `${border}\n${centeredTitle}\n${border}`;
}
console.log(createHeader('Monthly Sales Report'));
// ==================================================
// ========== Monthly Sales Report =================
// ==================================================
ボックス型の装飾テキストを生成する例です。
javascriptimport { pad } from 'lodash';
// ボックス型メッセージを生成
function createBox(message, width = 40) {
const topBottom = '+' + '-'.repeat(width - 2) + '+';
const centeredMessage = pad(message, width - 4);
const content = `| ${centeredMessage} |`;
return `${topBottom}\n${content}\n${topBottom}`;
}
console.log(createBox('Success!', 30));
// +----------------------------+
// | Success! |
// +----------------------------+
repeat:パターン生成
文字列を繰り返す repeat は、区切り線や装飾に使用します。
javascriptimport { repeat } from 'lodash';
// 区切り線を生成
const separator = repeat('-', 50);
console.log(separator);
// --------------------------------------------------
javascript// 異なる種類の区切り線
const thinLine = repeat('─', 40);
const thickLine = repeat('═', 40);
const doubleLine = repeat('=', 40);
const starLine = repeat('*', 40);
console.log(thinLine); // ────────────────────────────────────────
console.log(thickLine); // ════════════════════════════════════════
console.log(doubleLine); // ========================================
console.log(starLine); // ****************************************
プログレスバーの視覚的表現にも活用できます。
javascriptimport { repeat } from 'lodash';
// プログレスバーを生成
function createProgressBar(progress, total, width = 30) {
const percentage = Math.floor((progress / total) * 100);
const filledWidth = Math.floor(
(progress / total) * width
);
const emptyWidth = width - filledWidth;
const filled = repeat('█', filledWidth);
const empty = repeat('░', emptyWidth);
return `[${filled}${empty}] ${percentage}%`;
}
console.log(createProgressBar(25, 100)); // [███████░░░░░░░░░░░░░░░░░░░░░] 25%
console.log(createProgressBar(50, 100)); // [███████████████░░░░░░░░░░░░░] 50%
console.log(createProgressBar(75, 100)); // [██████████████████████░░░░░░] 75%
console.log(createProgressBar(100, 100)); // [██████████████████████████████] 100%
トリム・整形の実践例
トリム関数は、ユーザー入力の正規化や、テキストデータのクリーニングに欠かせません。
trim:フォーム入力の正規化
ユーザーが入力フォームに誤って入れてしまった空白を削除します。
javascriptimport { trim } from 'lodash';
// ユーザー名の入力を正規化
const userInput = ' john.doe@example.com ';
const cleanedEmail = trim(userInput);
console.log(cleanedEmail); // "john.doe@example.com"
複数のフィールドを一括で正規化する関数です。
javascriptimport { trim } from 'lodash';
// フォームデータを正規化
function normalizeFormData(formData) {
const normalized = {};
for (const key in formData) {
if (typeof formData[key] === 'string') {
normalized[key] = trim(formData[key]);
} else {
normalized[key] = formData[key];
}
}
return normalized;
}
javascript// 使用例
const rawFormData = {
username: ' johndoe ',
email: ' john@example.com ',
age: 30, // 数値はそのまま
bio: ' Software Developer ',
};
const cleanedData = normalizeFormData(rawFormData);
console.log(cleanedData);
// {
// username: 'johndoe',
// email: 'john@example.com',
// age: 30,
// bio: 'Software Developer'
// }
バリデーション前の必須処理として組み込むこともできます。
javascriptimport { trim } from 'lodash';
// バリデーション付き入力処理
function validateEmail(email) {
const cleaned = trim(email);
if (cleaned.length === 0) {
return { valid: false, error: 'Email is required' };
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(cleaned)) {
return { valid: false, error: 'Invalid email format' };
}
return { valid: true, value: cleaned };
}
console.log(validateEmail(' test@example.com '));
// { valid: true, value: 'test@example.com' }
console.log(validateEmail(' '));
// { valid: false, error: 'Email is required' }
trimStart、trimEnd:部分的なトリム
先頭または末尾のみをトリムする必要がある場合に使用します。
javascriptimport { trimStart, trimEnd } from 'lodash';
// インデントを削除(末尾の空白は保持)
const indentedText = ' Hello World ';
console.log(trimStart(indentedText)); // "Hello World "
console.log(trimEnd(indentedText)); // " Hello World"
コードエディタのような行末スペース削除処理です。
javascriptimport { trimEnd } from 'lodash';
// 複数行テキストの各行末尾スペースを削除
function removeTrailingSpaces(text) {
return text
.split('\n')
.map((line) => trimEnd(line))
.join('\n');
}
const code = `function hello() {
console.log('Hello');
} `;
const cleaned = removeTrailingSpaces(code);
console.log(cleaned);
// function hello() {
// console.log('Hello');
// }
ログファイルのパース処理での活用例です。
javascriptimport { trimStart } from 'lodash';
// ログエントリから先頭のタイムスタンプ部分を除去
function parseLogEntry(logLine) {
// タイムスタンプと空白を削除してメッセージ部分を取得
// "[2025-11-18 10:30:45] Error occurred" → "Error occurred"
const withoutBrackets = logLine.replace(
/^\[.*?\]\s*/,
''
);
return trimStart(withoutBrackets);
}
const logLines = [
'[2025-11-18 10:30:45] Error occurred',
'[2025-11-18 10:31:12] Warning: Low memory',
'[2025-11-18 10:32:00]Info: Process completed',
];
logLines.forEach((line) => {
console.log(parseLogEntry(line));
});
// Error occurred
// Warning: Low memory
// Info: Process completed
truncate:長文の省略表示
長いテキストを指定文字数で切り詰めて、省略記号を付加します。
javascriptimport { truncate } from 'lodash';
// 記事の要約を生成
const longText =
'This is a very long article about Lodash string utilities and how to use them effectively in your projects.';
const summary = truncate(longText, { length: 50 });
console.log(summary);
// "This is a very long article about Lodash str..."
オプションを詳細に指定する例です。
javascriptimport { truncate } from 'lodash';
const text = 'This is a very long article about Lodash';
// 省略記号をカスタマイズ
const custom1 = truncate(text, {
length: 30,
omission: ' [続きを読む]',
});
console.log(custom1);
// "This is a very lon [続きを読む]"
// 単語の途中で切らない
const custom2 = truncate(text, {
length: 30,
separator: ' ',
});
console.log(custom2);
// "This is a very long article..."
// 正規表現で区切り位置を指定
const custom3 = truncate(text, {
length: 30,
separator: /,? +/,
});
console.log(custom3);
// "This is a very long article..."
カード型 UI のテキスト表示に活用する実践例です。
javascriptimport { truncate } from 'lodash';
// ブログカードコンポーネント用のデータ整形
function formatBlogCard(article) {
return {
title: truncate(article.title, { length: 60 }),
description: truncate(article.description, {
length: 120,
separator: ' ',
omission: '...',
}),
author: article.author,
};
}
const article = {
title:
'Comprehensive Guide to Lodash String Utilities: Case Conversion, Padding, and Trimming Techniques',
description:
'In this detailed tutorial, we will explore various string manipulation techniques using Lodash library, including camelCase, kebabCase, snakeCase conversions, as well as padding and trimming operations that are essential for modern web development.',
author: 'John Doe',
};
const formattedCard = formatBlogCard(article);
console.log(formattedCard);
// {
// title: 'Comprehensive Guide to Lodash String Utilities: Case...',
// description: 'In this detailed tutorial, we will explore various string manipulation techniques using Lodash library, including...',
// author: 'John Doe'
// }
実践的な組み合わせパターン
複数の関数を組み合わせることで、より高度な文字列処理が可能になります。
API レスポンスの完全な正規化
API から取得したデータを、フロントエンドで使いやすい形式に一括変換します。
javascriptimport { camelCase, trim } from 'lodash';
// API レスポンスを完全に正規化
function normalizeApiResponse(data) {
if (typeof data !== 'object' || data === null) {
return data;
}
if (Array.isArray(data)) {
return data.map((item) => normalizeApiResponse(item));
}
const normalized = {};
for (const key in data) {
if (data.hasOwnProperty(key)) {
// キーをcamelCase に変換
const camelKey = camelCase(key);
const value = data[key];
// 文字列値はtrim、オブジェクトは再帰的に処理
if (typeof value === 'string') {
normalized[camelKey] = trim(value);
} else if (typeof value === 'object') {
normalized[camelKey] = normalizeApiResponse(value);
} else {
normalized[camelKey] = value;
}
}
}
return normalized;
}
javascript// 使用例
const apiData = {
user_name: ' John Doe ',
user_email: ' john@example.com ',
profile_data: {
company_name: ' Tech Corp ',
job_title: ' Senior Developer ',
},
user_tags: [' javascript ', ' react '],
};
const normalized = normalizeApiResponse(apiData);
console.log(normalized);
// {
// userName: 'John Doe',
// userEmail: 'john@example.com',
// profileData: {
// companyName: 'Tech Corp',
// jobTitle: 'Senior Developer'
// },
// userTags: ['javascript', 'react']
// }
フォームバリデーションシステム
入力値の正規化とバリデーションを統合したシステムです。
javascriptimport { trim, capitalize } from 'lodash';
// 包括的なフォームバリデーター
class FormValidator {
static validateUsername(username) {
const cleaned = trim(username);
if (cleaned.length === 0) {
return {
valid: false,
error: 'Username is required',
};
}
if (cleaned.length < 3) {
return {
valid: false,
error: 'Username must be at least 3 characters',
};
}
if (!/^[a-zA-Z0-9_]+$/.test(cleaned)) {
return {
valid: false,
error:
'Username can only contain letters, numbers, and underscores',
};
}
return { valid: true, value: cleaned };
}
static validateEmail(email) {
const cleaned = trim(email).toLowerCase();
if (cleaned.length === 0) {
return { valid: false, error: 'Email is required' };
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(cleaned)) {
return {
valid: false,
error: 'Invalid email format',
};
}
return { valid: true, value: cleaned };
}
static validateName(name) {
const cleaned = trim(name);
if (cleaned.length === 0) {
return { valid: false, error: 'Name is required' };
}
// 各単語の先頭を大文字化
const capitalized = cleaned
.split(' ')
.map((word) => capitalize(word))
.join(' ');
return { valid: true, value: capitalized };
}
}
javascript// 使用例
const usernameResult =
FormValidator.validateUsername(' john_doe ');
console.log(usernameResult);
// { valid: true, value: 'john_doe' }
const emailResult = FormValidator.validateEmail(
' JOHN@EXAMPLE.COM '
);
console.log(emailResult);
// { valid: true, value: 'john@example.com' }
const nameResult =
FormValidator.validateName(' john doe ');
console.log(nameResult);
// { valid: true, value: 'John Doe' }
ファイル名生成ユーティリティ
安全で一貫性のあるファイル名を生成するシステムです。
javascriptimport { kebabCase, snakeCase, padStart } from 'lodash';
// ファイル名生成ユーティリティ
class FileNameGenerator {
// URL セーフなファイル名を生成
static generateSafeFileName(name, extension) {
const safeName = kebabCase(name);
return `${safeName}.${extension}`;
}
// タイムスタンプ付きファイル名
static generateTimestampedFileName(name, extension) {
const safeName = kebabCase(name);
const timestamp = new Date().getTime();
return `${safeName}_${timestamp}.${extension}`;
}
// 連番付きファイル名
static generateSequentialFileName(
name,
index,
extension,
digits = 4
) {
const safeName = snakeCase(name);
const paddedIndex = padStart(
String(index),
digits,
'0'
);
return `${safeName}_${paddedIndex}.${extension}`;
}
// 日付付きファイル名
static generateDateFileName(name, extension) {
const safeName = kebabCase(name);
const date = new Date();
const year = date.getFullYear();
const month = padStart(
String(date.getMonth() + 1),
2,
'0'
);
const day = padStart(String(date.getDate()), 2, '0');
return `${safeName}_${year}${month}${day}.${extension}`;
}
}
javascript// 使用例
console.log(
FileNameGenerator.generateSafeFileName(
'My Document File',
'pdf'
)
);
// "my-document-file.pdf"
console.log(
FileNameGenerator.generateTimestampedFileName(
'User Avatar',
'jpg'
)
);
// "user-avatar_1700294400000.jpg"
console.log(
FileNameGenerator.generateSequentialFileName(
'Report File',
42,
'xlsx'
)
);
// "report_file_0042.xlsx"
console.log(
FileNameGenerator.generateDateFileName(
'Daily Backup',
'zip'
)
);
// "daily-backup_20251118.zip"
データエクスポート時の整形
CSV やテキストファイルにエクスポートする際の整形処理です。
javascriptimport { padEnd, truncate, upperCase } from 'lodash';
// データエクスポート用フォーマッター
class DataExporter {
// CSV 形式でエクスポート
static exportToCSV(data, columns) {
// ヘッダー行
const header = columns
.map((col) => col.label)
.join(',');
// データ行
const rows = data.map((row) => {
return columns
.map((col) => {
let value = row[col.key] || '';
// 長すぎる値は切り詰め
if (col.maxLength) {
value = truncate(String(value), {
length: col.maxLength,
omission: '...',
});
}
// カンマを含む場合はクォートで囲む
if (String(value).includes(',')) {
value = `"${value}"`;
}
return value;
})
.join(',');
});
return [header, ...rows].join('\n');
}
// テーブル形式でエクスポート
static exportToTable(data, columns) {
// 各列の最大幅を計算
const widths = columns.map((col) => {
const headerWidth = col.label.length;
const dataWidth = Math.max(
...data.map(
(row) => String(row[col.key] || '').length
)
);
return Math.max(
headerWidth,
dataWidth,
col.minWidth || 0
);
});
// ヘッダー行
const header = columns
.map((col, i) =>
padEnd(upperCase(col.label), widths[i])
)
.join(' | ');
// 区切り線
const separator = widths
.map((w) => '-'.repeat(w))
.join('-+-');
// データ行
const rows = data.map((row) => {
return columns
.map((col, i) => {
let value = String(row[col.key] || '');
// 切り詰め
if (value.length > widths[i]) {
value = truncate(value, {
length: widths[i],
omission: '...',
});
}
return padEnd(value, widths[i]);
})
.join(' | ');
});
return [header, separator, ...rows].join('\n');
}
}
javascript// 使用例
const products = [
{
id: 1,
name: 'Laptop Computer',
price: 1200,
stock: 15,
},
{ id: 2, name: 'Wireless Mouse', price: 25, stock: 150 },
{
id: 3,
name: 'Mechanical Keyboard with RGB Lighting',
price: 80,
stock: 45,
},
];
const columns = [
{ key: 'id', label: 'ID', minWidth: 5 },
{
key: 'name',
label: 'Product Name',
maxLength: 20,
minWidth: 20,
},
{ key: 'price', label: 'Price', minWidth: 8 },
{ key: 'stock', label: 'Stock', minWidth: 8 },
];
console.log(DataExporter.exportToTable(products, columns));
// ID | PRODUCT NAME | PRICE | STOCK
// ------+----------------------+----------+---------
// 1 | Laptop Computer | 1200 | 15
// 2 | Wireless Mouse | 25 | 150
// 3 | Mechanical Keyboa... | 80 | 45
パフォーマンス最適化のヒント
Lodash の文字列関数を使用する際のパフォーマンス最適化テクニックをご紹介します。
関数の個別インポート
バンドルサイズを最小化するため、必要な関数のみをインポートしましょう。
javascript// ❌ 避けるべき:ライブラリ全体をインポート
import _ from 'lodash';
const result = _.camelCase('hello world');
javascript// ✅ 推奨:必要な関数のみインポート
import { camelCase } from 'lodash';
const result = camelCase('hello world');
Webpack や Rollup などのバンドラーを使用している場合、個別インポートにより未使用のコードが自動的に除外されます。
繰り返し処理での関数再利用
ループ内で何度も同じ処理を行う場合、関数を事前に定義して再利用します。
javascriptimport { camelCase } from 'lodash';
// ✅ 効率的:関数を事前定義
const convertKeys = (obj) => {
const result = {};
for (const key in obj) {
result[camelCase(key)] = obj[key];
}
return result;
};
// 大量のデータを処理
const dataArray = [
/* 1000件のデータ */
];
const converted = dataArray.map(convertKeys);
メモ化による最適化
同じ入力に対して繰り返し処理を行う場合、結果をキャッシュすることで高速化できます。
javascriptimport { camelCase } from 'lodash';
// メモ化関数の実装
function memoize(fn) {
const cache = new Map();
return function (arg) {
if (cache.has(arg)) {
return cache.get(arg);
}
const result = fn(arg);
cache.set(arg, result);
return result;
};
}
// camelCase をメモ化
const memoizedCamelCase = memoize(camelCase);
// 同じ文字列を何度も変換する場合に効果的
console.log(memoizedCamelCase('user_name')); // 初回:計算実行
console.log(memoizedCamelCase('user_name')); // 2回目以降:キャッシュから取得
まとめ
Lodash の文字列ユーティリティは、日常的な開発業務において非常に強力なツールです。本記事では、case 変換・パディング・トリムの 3 つのカテゴリに焦点を当て、実践的な使用方法をご紹介しました。
主要なポイント
Case 変換 では、camelCase、kebabCase、snakeCase、startCase などを活用することで、API 連携時の命名規則変換や、コーディング規約の統一が簡単に実現できます。
パディング では、padStart、padEnd、pad を使用して、数値のゼロ埋めや、テーブル形式の整形、固定長データの生成が可能になりますね。
トリム・整形 では、trim、truncate などを活用することで、ユーザー入力の正規化や、UI 表示用のテキスト整形が効率的に行えます。
実務での活用指針
これらの関数を組み合わせることで、より複雑な文字列処理にも対応できます。API レスポンスの正規化、フォームバリデーション、ファイル名生成など、実践的なパターンを参考に、プロジェクトに適した実装を行ってください。
パフォーマンスを意識した個別インポートやメモ化の活用により、大規模なアプリケーションでも効率的に動作するコードを書くことができるでしょう。
Lodash の文字列ユーティリティをマスターすることで、コードの品質と開発効率が大きく向上します。ぜひ、今日から実務で活用してみてくださいね。
関連リンク
articleLodash 文字列ユーティリティ早見表:case 変換・パディング・トリムの極意
articleLodash-es と lodash の違いを理解してプロジェクトに最適導入
articleLodash を使う/使わない判断基準:2025 年のネイティブ API と併用戦略
articleLodash の組織運用ルール:no-restricted-imports と コーディング規約の設計
articleLodash のツリーシェイクが効かない問題を解決:import 形態とバンドラ設定
articleLodash vs Ramda vs Rambda:パイプライン記法・カリー化・DX を徹底比較
articleDevin vs 手動コードレビュー:バグ検出率と回帰不具合の実地検証レポート
articleLodash 文字列ユーティリティ早見表:case 変換・パディング・トリムの極意
articleLlamaIndex と LangChain を徹底比較:開発速度・可観測性・精度ベンチ
articleConvex で実現できること早見:チャット・コラボ・SaaS・ゲームの主要ユースケース総覧
articleLangChain 再ランキング手法の実測:Cohere/OpenAI ReRank/Cross-Encoder の効果
articleJotai 非同期で Suspense が発火しない問題の切り分けガイド
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来