T-CREATOR

【2025年最新版】lodashの全機能・関数一覧チートシート|用途別で迷わない使い方

【2025年最新版】lodashの全機能・関数一覧チートシート|用途別で迷わない使い方

JavaScript の開発において、複雑なデータ操作や配列処理を効率的に行うための強力なツールがlodashです。2025 年現在、モダン JavaScript の機能が充実した環境においても、lodash は依然として多くの開発者に愛用されています。

本記事では、lodash の全機能を用途別に整理し、実際の開発現場で迷わず使えるよう、具体的なサンプルコードとともに詳しく解説いたします。

lodashの概要

lodash は、JavaScript ユーティリティライブラリとして、配列、オブジェクト、文字列、関数などの操作を簡潔に記述できる 300 以上の関数を提供しています。2025 年の現在においても、その安定性と豊富な機能で多くのプロジェクトで採用されています。

用途例

  • 複雑なデータ構造の操作:ネストしたオブジェクトや配列の深いクローンや変換
  • パフォーマンスが重要な処理:大量のデータを効率的に処理したい場面
  • レガシーブラウザ対応:ES6+の機能が使えない環境での代替手段として活用

Array(配列)操作チートシート

配列操作は lodash の最も強力な機能の一つです。以下に主要な関数をまとめました。

#機能・項目名コマンド・記法例サンプルコード解説・補足
1配列の結合_.concat(array, [values])_.concat([1, 2], [3, 4])複数の配列や値を結合
2配列の差分_.difference(array, [values])_.difference([1, 2, 3], [2, 3])第一配列から第二配列の要素を除外
3配列の交差_.intersection([arrays])_.intersection([1, 2], [2, 3])複数配列の共通要素を取得
4配列の結合(集合)_.union([arrays])_.union([1, 2], [2, 3])複数配列をユニークに結合
5重複の除去_.uniq(array)_.uniq([1, 2, 2, 3])配列から重複要素を除去
6配列の平坦化_.flatten(array)_.flatten([1, [2, 3]])1 レベルの配列を平坦化
7深い平坦化_.flattenDeep(array)_.flattenDeep([1, [2, [3]]])全レベルの配列を平坦化
8配列の分割_.chunk(array, size)_.chunk([1, 2, 3, 4], 2)指定サイズで配列を分割
9配列の圧縮_.zip([arrays])_.zip([1, 2], [3, 4])複数配列を対応する位置で結合
10配列の解凍_.unzip(array)_.unzip([[1, 3], [2, 4]])zip 操作の逆変換
11最初の N 個取得_.take(array, n)_.take([1, 2, 3], 2)配列の先頭から N 個取得
12最後の N 個取得_.takeRight(array, n)_.takeRight([1, 2, 3], 2)配列の末尾から N 個取得
13最初の N 個削除_.drop(array, n)_.drop([1, 2, 3], 1)配列の先頭から N 個削除
14最後の N 個削除_.dropRight(array, n)_.dropRight([1, 2, 3], 1)配列の末尾から N 個削除
15条件満たす要素を削除_.dropWhile(array, predicate)_.dropWhile([1, 2, 3], n => n < 3)条件を満たす間、先頭から要素を削除

実用サンプル:配列操作

1. 複数配列の重複除去と結合

javascript// ECサイトのカテゴリ管理で重複するカテゴリを統合
const category1 = ['Electronics', 'Books', 'Clothing'];
const category2 = ['Books', 'Sports', 'Electronics'];
const category3 = ['Home', 'Books', 'Garden'];

// 全カテゴリを重複なく結合
const allCategories = _.union(
  category1,
  category2,
  category3
);
console.log(allCategories);
// => ['Electronics', 'Books', 'Clothing', 'Sports', 'Home', 'Garden']

2. データの分割処理

javascript// 大量のデータを一定サイズに分割してバッチ処理
const largeDataSet = Array.from(
  { length: 1000 },
  (_, i) => i + 1
);

// 100件ずつに分割
const batches = _.chunk(largeDataSet, 100);

// 各バッチを処理
batches.forEach((batch, index) => {
  console.log(`処理バッチ ${index + 1}: ${batch.length}件`);
  // バッチ処理のロジック
});

3. 配列の深い平坦化

javascript// ネストした配列データの平坦化
const nestedCategories = [
  'Electronics',
  ['Phones', ['iPhone', 'Android']],
  [
    'Computers',
    ['Desktop', 'Laptop', ['Gaming', 'Business']],
  ],
];

const flatCategories = _.flattenDeep(nestedCategories);
console.log(flatCategories);
// => ['Electronics', 'Phones', 'iPhone', 'Android', 'Computers', 'Desktop', 'Laptop', 'Gaming', 'Business']

Object(オブジェクト)操作チートシート

オブジェクトの操作は、API 応答の処理や設定の管理において頻繁に使用されます。

#機能・項目名コマンド・記法例サンプルコード解説・補足
1オブジェクトの結合_.assign(object, [sources])_.assign({a: 1}, {b: 2})プロパティを浅くコピー
2深いマージ_.merge(object, [sources])_.merge({a: {b: 1}}, {a: {c: 2}})オブジェクトを深くマージ
3プロパティの取得_.get(object, path, [defaultValue])_.get(obj, 'a.b.c', 'default')安全にネストしたプロパティ取得
4プロパティの設定_.set(object, path, value)_.set(obj, 'a.b.c', 'value')ネストしたプロパティを設定
5プロパティの存在確認_.has(object, path)_.has(obj, 'a.b.c')プロパティの存在チェック
6プロパティの削除_.unset(object, path)_.unset(obj, 'a.b.c')ネストしたプロパティを削除
7キーの一覧取得_.keys(object)_.keys({a: 1, b: 2})オブジェクトのキー配列を取得
8値の一覧取得_.values(object)_.values({a: 1, b: 2})オブジェクトの値配列を取得
9キー・値ペア取得_.toPairs(object)_.toPairs({a: 1, b: 2})[key, value]のペア配列を取得
10プロパティの選択_.pick(object, [paths])_.pick(obj, ['a', 'b'])指定したプロパティのみ抽出
11プロパティの除外_.omit(object, [paths])_.omit(obj, ['c', 'd'])指定したプロパティを除外
12値のマッピング_.mapValues(object, iteratee)_.mapValues(obj, v => v * 2)値を変換した新しいオブジェクト
13キーのマッピング_.mapKeys(object, iteratee)_.mapKeys(obj, (v, k) => k.toUpperCase())キーを変換した新しいオブジェクト
14オブジェクトの反転_.invert(object)_.invert({a: 1, b: 2})キーと値を入れ替え
15デフォルト値の設定_.defaults(object, [sources])_.defaults({a: 1}, {a: 2, b: 3})存在しないプロパティのみ設定

実用サンプル:オブジェクト操作

1. API 応答の安全な取得

javascript// API応答から安全にデータを取得
const apiResponse = {
  data: {
    user: {
      profile: {
        name: 'John Doe',
        settings: {
          theme: 'dark',
        },
      },
    },
  },
};

// 安全にネストしたプロパティを取得
const userName = _.get(
  apiResponse,
  'data.user.profile.name',
  'Unknown User'
);
const userTheme = _.get(
  apiResponse,
  'data.user.profile.settings.theme',
  'light'
);
const userAge = _.get(
  apiResponse,
  'data.user.profile.age',
  0
);

console.log(
  `ユーザー: ${userName}, テーマ: ${userTheme}, 年齢: ${userAge}`
);
// => ユーザー: John Doe, テーマ: dark, 年齢: 0

2. 設定オブジェクトの管理

javascript// アプリケーション設定の管理
const defaultConfig = {
  api: {
    timeout: 5000,
    retryCount: 3,
    baseURL: 'https://api.example.com',
  },
  ui: {
    theme: 'light',
    language: 'ja',
  },
};

const userConfig = {
  api: {
    timeout: 10000,
  },
  ui: {
    theme: 'dark',
  },
};

// 設定をマージ(深いマージ)
const finalConfig = _.merge({}, defaultConfig, userConfig);
console.log(finalConfig);
// => {
//   api: { timeout: 10000, retryCount: 3, baseURL: 'https://api.example.com' },
//   ui: { theme: 'dark', language: 'ja' }
// }

3. フォームデータの処理

javascript// フォームの送信データから必要なフィールドのみ抽出
const formData = {
  name: 'John Doe',
  email: 'john@example.com',
  password: 'secret123',
  confirmPassword: 'secret123',
  terms: true,
  newsletter: false,
  timestamp: Date.now(),
};

// API送信用に必要なフィールドのみ抽出
const apiData = _.pick(formData, [
  'name',
  'email',
  'password',
]);

// 確認用フィールドを除外
const cleanData = _.omit(formData, [
  'confirmPassword',
  'timestamp',
]);

console.log('API送信データ:', apiData);
console.log('クリーンデータ:', cleanData);

Collection(コレクション)操作チートシート

配列とオブジェクトの両方に対応した汎用的なコレクション操作関数です。

#機能・項目名コマンド・記法例サンプルコード解説・補足
1要素の検索_.find(collection, predicate)_.find(users, {age: 25})条件に合う最初の要素を取得
2要素のフィルタリング_.filter(collection, predicate)_.filter(users, u => u.age > 18)条件に合う要素の配列を取得
3要素の変換_.map(collection, iteratee)_.map(users, 'name')各要素を変換した新しい配列
4要素の削除_.reject(collection, predicate)_.reject(users, {active: false})条件に合わない要素を取得
5要素の分割_.partition(collection, predicate)_.partition(users, u => u.age > 18)条件で要素を 2 つの配列に分割
6グルーピング_.groupBy(collection, iteratee)_.groupBy(users, 'department')指定キーで要素をグループ化
7カウント_.countBy(collection, iteratee)_.countBy(users, 'active')指定キーで要素をカウント
8ソート_.orderBy(collection, iteratees, orders)_.orderBy(users, ['age'], ['desc'])複数条件でソート
9ソート(簡易版)_.sortBy(collection, iteratees)_.sortBy(users, 'name')指定キーでソート
10各要素の実行_.forEach(collection, iteratee)_.forEach(users, u => console.log(u.name))各要素に対して処理を実行
11条件チェック(全て)_.every(collection, predicate)_.every(users, u => u.age > 0)全要素が条件を満たすかチェック
12条件チェック(一部)_.some(collection, predicate)_.some(users, {active: true})一部要素が条件を満たすかチェック
13配列の先頭要素_.head(array)_.head([1, 2, 3])配列の最初の要素を取得
14配列の末尾要素_.last(array)_.last([1, 2, 3])配列の最後の要素を取得
15配列のサイズ_.size(collection)_.size([1, 2, 3])コレクションのサイズを取得

実用サンプル:コレクション操作

1. ユーザーデータの管理

javascript// ユーザーデータの管理と検索
const users = [
  {
    id: 1,
    name: 'Alice',
    age: 25,
    department: 'Engineering',
    active: true,
  },
  {
    id: 2,
    name: 'Bob',
    age: 30,
    department: 'Marketing',
    active: false,
  },
  {
    id: 3,
    name: 'Charlie',
    age: 35,
    department: 'Engineering',
    active: true,
  },
  {
    id: 4,
    name: 'Diana',
    age: 28,
    department: 'Sales',
    active: true,
  },
];

// アクティブなユーザーのみ抽出
const activeUsers = _.filter(users, { active: true });
console.log('アクティブユーザー:', activeUsers.length);

// 部署別にグループ化
const usersByDept = _.groupBy(users, 'department');
console.log(
  '部署別ユーザー数:',
  _.mapValues(usersByDept, (users) => users.length)
);

// 年齢でソート
const usersByAge = _.orderBy(users, ['age'], ['desc']);
console.log('年齢順ユーザー:', _.map(usersByAge, 'name'));

2. 商品データの分析

javascript// 商品データの分析
const products = [
  {
    id: 1,
    name: 'Laptop',
    price: 1200,
    category: 'Electronics',
    inStock: true,
  },
  {
    id: 2,
    name: 'Phone',
    price: 800,
    category: 'Electronics',
    inStock: false,
  },
  {
    id: 3,
    name: 'Desk',
    price: 300,
    category: 'Furniture',
    inStock: true,
  },
  {
    id: 4,
    name: 'Chair',
    price: 150,
    category: 'Furniture',
    inStock: true,
  },
];

// 在庫ありの商品を価格順でソート
const availableProducts = _.chain(products)
  .filter({ inStock: true })
  .orderBy(['price'], ['asc'])
  .value();

// カテゴリ別の平均価格
const avgPriceByCategory = _.mapValues(
  _.groupBy(products, 'category'),
  (products) => _.meanBy(products, 'price')
);

console.log(
  '在庫あり商品:',
  _.map(availableProducts, 'name')
);
console.log('カテゴリ別平均価格:', avgPriceByCategory);

String(文字列)操作チートシート

文字列の操作や変換に関する関数群です。

#機能・項目名コマンド・記法例サンプルコード解説・補足
1キャメルケース変換_.camelCase(string)_.camelCase('hello world')hello world → helloWorld
2スネークケース変換_.snakeCase(string)_.snakeCase('helloWorld')helloWorld → hello_world
3ケバブケース変換_.kebabCase(string)_.kebabCase('helloWorld')helloWorld → hello-world
4先頭文字大文字_.capitalize(string)_.capitalize('hello')hello → Hello
5文字列の切り取り_.truncate(string, options)_.truncate('hello world', {length: 8})指定長で切り取り
6文字列の埋め込み_.pad(string, length, chars)_.pad('42', 4, '0')文字列を指定長まで埋め込み
7左埋め込み_.padStart(string, length, chars)_.padStart('42', 4, '0')左側に文字を埋め込み
8右埋め込み_.padEnd(string, length, chars)_.padEnd('42', 4, '0')右側に文字を埋め込み
9文字列の繰り返し_.repeat(string, n)_.repeat('abc', 3)文字列を n 回繰り返し
10空白の除去_.trim(string, chars)_.trim(' hello ')前後の空白を除去
11左空白の除去_.trimStart(string, chars)_.trimStart(' hello')左側の空白を除去
12右空白の除去_.trimEnd(string, chars)_.trimEnd('hello ')右側の空白を除去
13大文字変換_.upperCase(string)_.upperCase('hello world')HELLO WORLD
14小文字変換_.lowerCase(string)_.lowerCase('HELLO WORLD')hello world
15文字列の置換_.replace(string, pattern, replacement)_.replace('hello', 'l', 'x')文字列の置換

実用サンプル:文字列操作

1. API エンドポイントの生成

javascript// APIエンドポイントの動的生成
const apiEndpoints = [
  'user profile',
  'product catalog',
  'order history',
  'payment methods',
];

// キャメルケースとケバブケースに変換
const camelCaseEndpoints = _.map(apiEndpoints, (endpoint) =>
  _.camelCase(endpoint)
);

const kebabCaseEndpoints = _.map(
  apiEndpoints,
  (endpoint) => `/api/${_.kebabCase(endpoint)}`
);

console.log('キャメルケース:', camelCaseEndpoints);
// => ['userProfile', 'productCatalog', 'orderHistory', 'paymentMethods']

console.log('API URL:', kebabCaseEndpoints);
// => ['/api/user-profile', '/api/product-catalog', '/api/order-history', '/api/payment-methods']

2. ユーザー入力の正規化

javascript// フォーム入力値の正規化
const userInputs = [
  '  John Doe  ',
  'jane.smith@example.com  ',
  '  PRODUCT-NAME  ',
  '12345',
];

// 各入力値を適切に正規化
const normalizedInputs = _.map(userInputs, (input) => {
  const trimmed = _.trim(input);

  // メール形式の場合は小文字に
  if (_.includes(trimmed, '@')) {
    return _.lowerCase(trimmed);
  }

  // 数字のみの場合はパディング
  if (/^\d+$/.test(trimmed)) {
    return _.padStart(trimmed, 6, '0');
  }

  // その他は先頭大文字
  return _.capitalize(trimmed);
});

console.log('正規化後:', normalizedInputs);
// => ['John doe', 'jane.smith@example.com', 'Product-name', '012345']

Function(関数)操作チートシート

関数の制御や最適化に関する関数群です。

#機能・項目名コマンド・記法例サンプルコード解説・補足
1関数の遅延実行_.debounce(func, wait)_.debounce(saveData, 300)連続実行を防ぐ
2関数の間隔制御_.throttle(func, wait)_.throttle(updateUI, 100)実行頻度を制限
3一度だけ実行_.once(func)_.once(initialize)関数を一度だけ実行
4関数の遅延_.delay(func, wait, [args])_.delay(console.log, 1000, 'hello')指定時間後に関数実行
5関数の前後処理_.before(n, func)_.before(3, saveData)n 回目より前のみ実行
6関数の回数制限_.after(n, func)_.after(3, cleanup)n 回目以降のみ実行
7関数の部分適用_.partial(func, [partials])_.partial(multiply, 2)引数の一部を固定
8関数の結合_.flow([funcs])_.flow([add1, multiply2])関数を順番に実行
9関数の逆結合_.flowRight([funcs])_.flowRight([multiply2, add1])関数を逆順に実行
10関数の否定_.negate(predicate)_.negate(isEven)関数の結果を否定
11関数の条件分岐_.cond(pairs)_.cond([[isEven, 'even'], [isOdd, 'odd']])条件に応じて関数を実行
12関数の結果記憶_.memoize(func, [resolver])_.memoize(fibonacci)関数の結果をキャッシュ
13関数の引数反転_.flip(func)_.flip(Math.pow)関数の引数順序を反転
14関数の引数再配置_.rearg(func, indexes)_.rearg(func, [2, 0, 1])引数の順序を変更
15関数の引数変換_.overArgs(func, [transforms])_.overArgs(Math.max, [Math.abs])各引数を変換してから実行

実用サンプル:関数操作

1. 検索機能の最適化

javascript// 検索APIの呼び出し頻度を制御
const searchAPI = async (query) => {
  console.log(`検索実行: ${query}`);
  // API呼び出しのシミュレーション
  return fetch(`/api/search?q=${query}`);
};

// デバウンス処理で連続入力を制御
const debouncedSearch = _.debounce(searchAPI, 300);

// 使用例(入力フィールドでの利用)
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', (e) => {
  debouncedSearch(e.target.value);
});

// スクロールイベントの最適化
const updateScrollPosition = () => {
  console.log('スクロール位置更新');
  // 重い処理
};

const throttledScroll = _.throttle(
  updateScrollPosition,
  100
);
window.addEventListener('scroll', throttledScroll);

2. 初期化処理の制御

javascript// 初期化処理を一度だけ実行
const initializeApp = _.once(() => {
  console.log('アプリケーション初期化');
  // 初期化処理
  setupEventListeners();
  loadUserPreferences();
  connectWebSocket();
});

// 複数回呼び出されても一度だけ実行される
initializeApp(); // 実行される
initializeApp(); // 実行されない
initializeApp(); // 実行されない

// 関数の部分適用で汎用的な処理を作成
const logWithLevel = (level, message) => {
  console.log(`[${level}] ${message}`);
};

const logInfo = _.partial(logWithLevel, 'INFO');
const logError = _.partial(logWithLevel, 'ERROR');

logInfo('処理が完了しました'); // [INFO] 処理が完了しました
logError('エラーが発生しました'); // [ERROR] エラーが発生しました

Math(数学)操作チートシート

数値計算や統計処理に関する関数群です。

#機能・項目名コマンド・記法例サンプルコード解説・補足
1値の合計_.sum(array)_.sum([1, 2, 3])配列の合計値
2条件付き合計_.sumBy(array, iteratee)_.sumBy(products, 'price')プロパティの合計値
3平均値_.mean(array)_.mean([1, 2, 3])配列の平均値
4条件付き平均_.meanBy(array, iteratee)_.meanBy(products, 'price')プロパティの平均値
5最大値_.max(array)_.max([1, 2, 3])配列の最大値
6条件付き最大値_.maxBy(array, iteratee)_.maxBy(products, 'price')プロパティの最大値
7最小値_.min(array)_.min([1, 2, 3])配列の最小値
8条件付き最小値_.minBy(array, iteratee)_.minBy(products, 'price')プロパティの最小値
9値の範囲制限_.clamp(number, lower, upper)_.clamp(10, 0, 5)値を指定範囲内に制限
10値の範囲内判定_.inRange(number, start, end)_.inRange(2, 0, 5)値が範囲内かチェック
11ランダム値_.random(lower, upper, floating)_.random(1, 100)指定範囲の乱数生成
12値の加算_.add(augend, addend)_.add(6, 4)2 つの値を加算
13値の減算_.subtract(minuend, subtrahend)_.subtract(6, 4)2 つの値を減算
14値の乗算_.multiply(multiplier, multiplicand)_.multiply(6, 4)2 つの値を乗算
15値の除算_.divide(dividend, divisor)_.divide(6, 4)2 つの値を除算

実用サンプル:数学操作

1. 売上データの分析

javascript// 月別売上データの分析
const salesData = [
  { month: '1月', sales: 1200000, orders: 450 },
  { month: '2月', sales: 1450000, orders: 520 },
  { month: '3月', sales: 1680000, orders: 600 },
  { month: '4月', sales: 1320000, orders: 480 },
  { month: '5月', sales: 1580000, orders: 580 },
];

// 売上統計の計算
const totalSales = _.sumBy(salesData, 'sales');
const averageSales = _.meanBy(salesData, 'sales');
const maxSalesMonth = _.maxBy(salesData, 'sales');
const minSalesMonth = _.minBy(salesData, 'sales');

console.log(`総売上: ${totalSales.toLocaleString()}円`);
console.log(
  `平均売上: ${Math.round(averageSales).toLocaleString()}円`
);
console.log(
  `最高売上月: ${
    maxSalesMonth.month
  } (${maxSalesMonth.sales.toLocaleString()}円)`
);
console.log(
  `最低売上月: ${
    minSalesMonth.month
  } (${minSalesMonth.sales.toLocaleString()}円)`
);

2. 価格計算システム

javascript// 商品価格の計算と調整
const products = [
  { name: 'ノートPC', basePrice: 89800, discount: 0.1 },
  { name: 'マウス', basePrice: 2980, discount: 0.05 },
  { name: 'キーボード', basePrice: 12800, discount: 0.15 },
];

// 価格計算の処理
const calculatePrice = (product) => {
  const discountedPrice = _.multiply(
    product.basePrice,
    _.subtract(1, product.discount)
  );
  // 価格を100円単位に調整
  return _.clamp(
    Math.round(discountedPrice / 100) * 100,
    0,
    product.basePrice
  );
};

const finalProducts = _.map(products, (product) => ({
  ...product,
  finalPrice: calculatePrice(product),
  savings: _.subtract(
    product.basePrice,
    calculatePrice(product)
  ),
}));

console.log('価格計算結果:');
finalProducts.forEach((product) => {
  console.log(
    `${
      product.name
    }: ${product.finalPrice.toLocaleString()}円 (${product.savings.toLocaleString()}円お得)`
  );
});

Utility(ユーティリティ)操作チートシート

その他の便利な関数群です。

#機能・項目名コマンド・記法例サンプルコード解説・補足
1深いクローン_.cloneDeep(value)_.cloneDeep(object)オブジェクトの完全コピー
2浅いクローン_.clone(value)_.clone(object)オブジェクトのコピー
3深い比較_.isEqual(value, other)_.isEqual(obj1, obj2)オブジェクトの内容比較
4空の判定_.isEmpty(value)_.isEmpty([])値が空かチェック
5null/undefined 判定_.isNil(value)_.isNil(null)null/undefined かチェック
6配列の判定_.isArray(value)_.isArray([])配列かチェック
7オブジェクトの判定_.isObject(value)_.isObject({})オブジェクトかチェック
8文字列の判定_.isString(value)_.isString('hello')文字列かチェック
9数値の判定_.isNumber(value)_.isNumber(42)数値かチェック
10関数の判定_.isFunction(value)_.isFunction(() => {})関数かチェック
11日付の判定_.isDate(value)_.isDate(new Date())日付かチェック
12正規表現の判定_.isRegExp(value)_.isRegExp(​/​abc​/​)正規表現かチェック
13有限数の判定_.isFinite(value)_.isFinite(42)有限数かチェック
14整数の判定_.isInteger(value)_.isInteger(42)整数かチェック
15範囲の生成_.range(start, end, step)_.range(0, 10, 2)数値の範囲を生成

実用サンプル:ユーティリティ操作

1. データの検証とクローン

javascript// フォームデータの検証と処理
const validateAndProcessForm = (formData) => {
  // 入力値の検証
  const validations = {
    name:
      _.isString(formData.name) &&
      !_.isEmpty(formData.name),
    email:
      _.isString(formData.email) &&
      _.includes(formData.email, '@'),
    age:
      _.isNumber(formData.age) &&
      _.isInteger(formData.age) &&
      formData.age > 0,
    preferences:
      _.isObject(formData.preferences) &&
      !_.isEmpty(formData.preferences),
  };

  // 全ての検証が通った場合のみ処理
  if (_.every(validations)) {
    // 元データを変更せずに処理用データを作成
    const processedData = _.cloneDeep(formData);

    // 処理用データの加工
    processedData.name = _.trim(processedData.name);
    processedData.email = _.toLower(processedData.email);

    return { success: true, data: processedData };
  }

  return { success: false, errors: validations };
};

// 使用例
const formData = {
  name: '  John Doe  ',
  email: 'JOHN@EXAMPLE.COM',
  age: 25,
  preferences: { theme: 'dark', notifications: true },
};

const result = validateAndProcessForm(formData);
console.log(result);

2. 設定データの比較と更新

javascript// 設定データの変更検出
const oldSettings = {
  theme: 'light',
  language: 'ja',
  notifications: {
    email: true,
    push: false,
  },
};

const newSettings = {
  theme: 'dark',
  language: 'ja',
  notifications: {
    email: true,
    push: true,
  },
};

// 設定変更の検出
const hasChanged = !_.isEqual(oldSettings, newSettings);

if (hasChanged) {
  console.log('設定が変更されました');

  // 変更された項目を特定
  const changedFields = [];

  _.forOwn(newSettings, (value, key) => {
    if (!_.isEqual(oldSettings[key], value)) {
      changedFields.push(key);
    }
  });

  console.log('変更された項目:', changedFields);

  // 変更ログの記録
  const changeLog = {
    timestamp: new Date(),
    changes: changedFields,
    oldSettings: _.cloneDeep(oldSettings),
    newSettings: _.cloneDeep(newSettings),
  };

  console.log('変更ログ:', changeLog);
}

よくある落とし穴・注意点

1. パフォーマンスの問題

javascript// ❌ 悪い例:チェーンメソッドの過度な使用
const result = _.chain(largeArray)
  .filter((item) => item.active)
  .map((item) => item.name)
  .sortBy()
  .value();

// ✅ 良い例:ネイティブメソッドとの組み合わせ
const result = largeArray
  .filter((item) => item.active)
  .map((item) => item.name)
  .sort();

2. バンドルサイズの問題

javascript// ❌ 悪い例:ライブラリ全体をインポート
import _ from 'lodash';

// ✅ 良い例:必要な関数のみインポート
import { debounce, throttle, cloneDeep } from 'lodash';
// または
import debounce from 'lodash/debounce';
import throttle from 'lodash/throttle';

3. 不変性の誤解

javascript// ❌ 悪い例:元の配列が変更される
const originalArray = [1, 2, 3];
const newArray = _.fill(originalArray, 0);
console.log(originalArray); // [0, 0, 0] - 元の配列が変更される!

// ✅ 良い例:元の配列を保護
const originalArray = [1, 2, 3];
const newArray = _.fill(_.clone(originalArray), 0);
console.log(originalArray); // [1, 2, 3] - 元の配列は変更されない

4. 型エラーの発生

javascript// ❌ 悪い例:undefined値の処理
const users = [
  { name: 'John', age: 25 },
  { name: 'Jane' }, // ageが未定義
  { name: 'Bob', age: 30 },
];

const averageAge = _.meanBy(users, 'age'); // NaN が返される

// ✅ 良い例:デフォルト値の設定
const averageAge = _.meanBy(users, (user) => user.age || 0);
// または
const averageAge = _.meanBy(_.filter(users, 'age'), 'age');

5. メモリリークの発生

javascript// ❌ 悪い例:イベントリスナーの重複設定
const debouncedHandler = _.debounce(handleInput, 300);

// イベントリスナーが重複して設定される
element.addEventListener('input', debouncedHandler);
element.addEventListener('input', debouncedHandler);

// ✅ 良い例:適切なクリーンアップ
const debouncedHandler = _.debounce(handleInput, 300);
element.addEventListener('input', debouncedHandler);

// 必要に応じてリスナーを削除
element.removeEventListener('input', debouncedHandler);

まとめ

lodash は、2025 年の現在においても、JavaScript 開発において非常に強力なツールです。300 以上の関数を提供し、配列・オブジェクト・文字列・関数など、あらゆるデータ操作を簡潔に記述できます。

しかしながら、モダン JavaScript の進化により、一部の機能はネイティブで実現可能になっています。バンドルサイズやパフォーマンスを考慮し、必要な機能のみを選択的にインポートする使い方が推奨されます。

適切に使用すれば、lodash は開発効率を大幅に向上させ、保守性の高いコードを書くことができる優秀なライブラリです。本記事のチートシートを参考に、実際のプロジェクトで活用してみてください。

関連リンク