🦔
javascriptで和集合、積集合、差集合、排他的論理和を取得する際のスニペット
はじめに
javascriptで和集合、積集合、差集合、排他的論理和を取得する際のスニペットです。
和集合(Union)
const A = [1, 2, 4, 5, 7];
const B = [2, 3, 5, 6, 8];
// -> [1, 2, 3, 4, 5, 6, 7, 8]
// setを使う
[...new Set([...A, ...B])]
// reduceを使う
[...A, ...B].reduce((cur, acc) => [...cur, ...(cur.includes(acc) ? [] : [acc])], [] as number[]
// lodashのunionを使う
_.union(A, B)
配列の要素がオブジェクトの場合
const A = [
{ id: 1, x: 1 },
{ id: 2, x: 1 },
{ id: 4, x: 1 },
{ id: 5, x: 1 },
{ id: 7, x: 1 },
];
const B = [
{ id: 2, x: 1 },
{ id: 3, x: 1 },
{ id: 5, x: 1 },
{ id: 6, x: 1 },
{ id: 8, x: 1 },
];
// -> idが同じものは同値とする
// [{ id: 1, x: 1 },
// { id: 2, x: 1 },
// { id: 3, x: 1 },
// { id: 4, x: 1 },
// { id: 5, x: 1 },
// { id: 6, x: 1 },
// { id: 7, x: 1 },
// { id: 8, x: 1 }];
// reduce使う
[...A, ...B].reduce((acc, cur) => [...acc, ...(acc.some((item) => item.id === cur.id) ? [] : [cur])],[] as { id: number; x: number }[])
// lodashのunionByを使う
_.unionBy(A, B, 'id')
// lodashのunionWithを使う
_.unionWith(A, B, (a, b) => a.id === b.id)
積集合(Intersection)
const A = [1, 2, 4, 5, 7];
const B = [2, 3, 5, 6, 8];
// -> [2, 5]
// filterを使う
A.filter((valA) => B.includes(valA))
// lodashのintersectionを使う
_.intersection(A, B)
配列の要素がオブジェクトの場合
const A = [
{ id: 1, x: 1 },
{ id: 2, x: 1 },
{ id: 4, x: 1 },
{ id: 5, x: 1 },
{ id: 7, x: 1 },
];
const B = [
{ id: 2, x: 1 },
{ id: 3, x: 1 },
{ id: 5, x: 1 },
{ id: 6, x: 1 },
{ id: 8, x: 1 },
];
// -> idが同じものは同値とする
// [{ id: 2, x: 1 },
// { id: 5, x: 1 },];
// filterを使う
A.filter((valA) => B.some((valB) => valB.id === valA.id))
// lodashのintersectionByを使う
_.intersectionBy(A, B, 'id')
// lodashのintersectionWithを使う
_.intersectionWith(A, B, (a, b) => a.id === b.id)
差集合(difference)
const A = [1, 2, 4, 5, 7];
const B = [2, 3, 5, 6, 8];
// -> A - Bは[1, 4, 7]
// filterを使う
A.filter((val) => !B.includes(val))
// reduceを使う
A.reduce((acc, cur) => [...acc, ...(B.includes(cur) ? [] : [cur])], [] as number[])
// lodashのdifferenceを使う
_.difference(A, B)
配列の要素がオブジェクトの場合
const A = [
{ id: 1, x: 1 },
{ id: 2, x: 1 },
{ id: 4, x: 1 },
{ id: 5, x: 1 },
{ id: 7, x: 1 },
];
const B = [
{ id: 2, x: 1 },
{ id: 3, x: 1 },
{ id: 5, x: 1 },
{ id: 6, x: 1 },
{ id: 8, x: 1 },
];
// -> idが同じものは同値とする
// [{ id: 1, x: 1 },
// { id: 4, x: 1 },
// { id: 7, x: 1 }]
// filterを使う
A.filter((valA) => !B.some((valB) => valA.id === valB.id))
// lodashのdifferenceByを使う
_.differenceBy(A, B, 'id')
// lodashのdifferenceWithを使う
_.differenceWith(A, B, (a, b) => a.id === b.id)
排他的論理和(xor)
const A = [1, 2, 4, 5, 7];
const B = [2, 3, 5, 6, 8];
// -> [1, 3, 4, 6, 7, 8];
// filterを使う
[...A, ...B].filter((val, _, arr) => arr.filter((v) => v === val).length === 1)
// reduceを使う
[...A, ...B].reduce((acc, cur, _, arr) => [...acc, ...(arr.filter((val) => val === cur).length === 1 ? [cur] : [])], [] as number[])
// lodashのxorを使う
_.xor(A, B)
配列の要素がオブジェクトの場合
const A = [
{ id: 1, x: 1 },
{ id: 2, x: 1 },
{ id: 4, x: 1 },
{ id: 5, x: 1 },
{ id: 7, x: 1 },
];
const B = [
{ id: 2, x: 1 },
{ id: 3, x: 1 },
{ id: 5, x: 1 },
{ id: 6, x: 1 },
{ id: 8, x: 1 },
];
// -> idが同じものは同値とする
// [{ id: 1, x: 1 },
// { id: 3, x: 1 },
// { id: 4, x: 1 },
// { id: 6, x: 1 },
// { id: 7, x: 1 },
// { id: 8, x: 1 }]
// filterを使う
[...A, ...B].filter((val, _, arr) => arr.filter((v) => v.id === val.id).length === 1)
// lodashのxorByを使う
_.xorBy(A, B, 'id')
// lodashのxorWithを使う
_.xorWith(A, B, (a, b) => a.id === b.id)
参照
Setでの集合論のメソッドは現在stage2のようです
Discussion