Делаем просто, ровно то, что спрошено:
const result = arr1.filter(function(n) {
return !this.has(n[0]);
}, new Set(arr2.map(n => n[0])));
Делаем сложно, решаем задачу в более общем виде:
function diff(data1, data2, compare = (a, b) => a === b) {
const arr = Array.isArray(data2) ? data2 : [...data2];
const result = [];
for (const n of data1) {
if (!arr.some(m => compare(m, n))) {
result.push(n);
}
}
return result;
}
const result = diff(
arr1,
arr2,
(a, b) => a.length === b.length && a.every((n, i) => Object.is(n, b[i]))
);
или
const diff = function*(data1, data2, keys = n => n) {
const tree = new Map;
for (const n of data2) []
.concat(keys(n))
.reduce((p, c) => p.set(c, p.get(c) ?? new Map).get(c), tree)
.set(this, true);
for (const n of data1) {
if (![].concat(keys(n)).reduce((p, c) => p?.get(c), tree)?.get(this)) {
yield n;
}
}
}.bind(Symbol());
const result = [...diff(arr1, arr2)];