Skip to content

Instantly share code, notes, and snippets.

@yukikim
Created December 1, 2024 16:39
Show Gist options
  • Save yukikim/9bccce3b470e1dfda86f85fb0f694bee to your computer and use it in GitHub Desktop.
Save yukikim/9bccce3b470e1dfda86f85fb0f694bee to your computer and use it in GitHub Desktop.
配列の差異

TypeScriptで2つの配列の違いを抽出するには、配列の比較を行い、片方にのみ存在する要素を特定するロジックを実装します。これには、filterSetを利用した方法が一般的です。

以下に具体例を示します。


実装例 1: シンプルな方法

function arrayDifference<T>(array1: T[], array2: T[]): T[] {
  return array1.filter(item => !array2.includes(item));
}

// 使用例
const array1 = [1, 2, 3, 4, 5];
const array2 = [4, 5, 6, 7, 8];

const diff1 = arrayDifference(array1, array2); // array1にあってarray2にない要素
console.log(diff1); // 出力: [1, 2, 3]

const diff2 = arrayDifference(array2, array1); // array2にあってarray1にない要素
console.log(diff2); // 出力: [6, 7, 8]

実装例 2: 両方向の違いを取得する

2つの配列の差分を完全に取得する(片方にのみ存在する要素の両方)場合の実装です。

function symmetricDifference<T>(array1: T[], array2: T[]): T[] {
  const diff1 = array1.filter(item => !array2.includes(item));
  const diff2 = array2.filter(item => !array1.includes(item));
  return [...diff1, ...diff2];
}

// 使用例
const array1 = [1, 2, 3, 4, 5];
const array2 = [4, 5, 6, 7, 8];

const result = symmetricDifference(array1, array2);
console.log(result); // 出力: [1, 2, 3, 6, 7, 8]

実装例 3: 高速化(Setを利用)

Setを利用すると、大規模な配列でも高速に差分を取得できます。

function arrayDifferenceSet<T>(array1: T[], array2: T[]): T[] {
  const set2 = new Set(array2);
  return array1.filter(item => !set2.has(item));
}

// 使用例
const array1 = [1, 2, 3, 4, 5];
const array2 = [4, 5, 6, 7, 8];

const diff1 = arrayDifferenceSet(array1, array2); // array1にあってarray2にない要素
console.log(diff1); // 出力: [1, 2, 3]

const diff2 = arrayDifferenceSet(array2, array1); // array2にあってarray1にない要素
console.log(diff2); // 出力: [6, 7, 8]

実装例 4: 完全な結果をオブジェクトで返す

function compareArrays<T>(array1: T[], array2: T[]): { onlyInArray1: T[]; onlyInArray2: T[] } {
  const onlyInArray1 = array1.filter(item => !array2.includes(item));
  const onlyInArray2 = array2.filter(item => !array1.includes(item));
  return { onlyInArray1, onlyInArray2 };
}

// 使用例
const array1 = [1, 2, 3, 4, 5];
const array2 = [4, 5, 6, 7, 8];

const result = compareArrays(array1, array2);
console.log(result);
// 出力:
// {
//   onlyInArray1: [1, 2, 3],
//   onlyInArray2: [6, 7, 8]
// }

実装例 5: オブジェクトの配列の差分を取得

配列の要素がオブジェクトの場合、includesSetでは直接比較できないため、キーの一致などを条件に比較します。

type Item = { id: number; name: string };

function arrayDifferenceByKey<T extends Record<string, any>>(
  array1: T[],
  array2: T[],
  key: keyof T
): T[] {
  const keySet = new Set(array2.map(item => item[key]));
  return array1.filter(item => !keySet.has(item[key]));
}

// 使用例
const array1 = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" },
];
const array2 = [
  { id: 2, name: "Bob" },
  { id: 4, name: "David" },
];

const diff = arrayDifferenceByKey(array1, array2, "id");
console.log(diff);
// 出力: [ { id: 1, name: 'Alice' }, { id: 3, name: 'Charlie' } ]

解説

  • 基本的な配列:
    • filterincludesを組み合わせれば十分。
  • Setの利用:
    • Setを使うと比較コストを削減できます。
  • オブジェクトの配列:
    • 特定のキーで比較する場合、Setを活用して効率的に処理可能です。

ニーズに応じてこれらの方法を選んでください!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment