Вот вариант максимально короткий и лёгкий для понимания:
const unique = (arr, keys) =>
arr.filter(n => n === arr.find(m => keys.every(k => m[k] === n[k])));
const result = unique(arr, [ 'model', 'param1', 'param2' ]);
Для вашего случая подходит, но вообще, есть ряд проблем:
Иногда косячит
Если объект присутствует в массиве несколько раз, то такие дубликаты не будут отброшены. Конкретно эта имеет тривиальное решение - вместо ссылок можно сравнивать индексы, под которыми объекты представлены в массиве:
- arr.filter(n => n === arr.find
+ arr.filter((n, i, a) => i === a.findIndex
Недостаточно гибко
Что если уникализировать надо не по собственно свойствам, а по каким-то производным от них значениям? Например, у объектов есть вложенные объекты, и нужны их свойства; или есть число, а нужен остаток от его деления на какое-то другое число; или есть дата, в которой важен только месяц.
Сложность
Фильтрация линейна, поиск тоже, одно внутри другого даёт квадрат.
Так что вот вариант потяжелее:
const unique = function(arr, keys = n => n) {
const picked = new Map;
return arr.filter((...args) => {
const p = []
.concat(keys(...args))
.reduce((acc, k) => acc.set(k, acc.get(k) || new Map).get(k), picked);
return !p.set(this, p.has(this)).get(this);
});
}.bind(Symbol());
const result = unique(arr, n => [ n.model, n.param1, n.param2 ]);