{ name: 'Corrupted Demon Eater', price: '3215.00', inStock: 1 },
{ name: 'Exalted Demon Eater', price: '1530.00', inStock: 1 },
{ name: 'Demon Eater', price: '2900.00', inStock: 1 },
{ name: 'Whalehook', price: '1000.00', inStock: 1 },
{ name: 'Whalehook', price: '590.00', inStock: 1 },
{ name: 'Whalehook', price: '259.20', inStock: 1 },
{ name: 'Whalehook', price: '259.15', inStock: 1 },
{ name: 'Autographed Whalehook', price: '243.00', inStock: 1 },
{ name: 'Autographed Whalehook', price: '344.00', inStock: 1 },
{ name: 'Autographed Whalehook', price: '199.00', inStock: 1 },
{ name: 'Inscribed Whalehook', price: '355.00', inStock: 1 },
{ name: 'Inscribed Whalehook', price: '655.00', inStock: 1 },
{ name: 'Inscribed Whalehook', price: '5555.00', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '345.00', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '96.18', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '95.00', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '266.71', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '85.00', inStock: 1 }
{ name: 'Exalted Demon Eater', price: '1530.00', inStock: 1 },
{ name: 'Autographed Whalehook', price: '199.00', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '85.00', inStock: 1 }
const getName = n => n.name.split(' ').pop();
// или
const getName = n => n.name.replace(/.+ /, '');
// или
const getName = n => n.name.match(/\S*$/)[0];
// или
const getName = n => n.name.slice(-~n.name.lastIndexOf(' '));
const result = Object.values(arr.reduce((min, n) => {
const name = getName(n);
min[name] = +min[name]?.price < +n.price ? min[name] : n;
return min;
}, {}));
function group(data, key, val = n => n) {
const getKey = key instanceof Function ? key : n => n[key];
const getVal = val instanceof Function ? val : n => n[val];
const result = new Map;
for (const n of data) {
const k = getKey(n);
result.set(k, result.get(k) ?? []).get(k).push(getVal(n));
}
return result;
}
function max(data, key = n => n) {
const getVal = key instanceof Function ? key : n => n[key];
let result = null;
for (const n of data) {
const val = getVal(n);
result = result?.[1] >= val ? result : [ n, val ];
}
return result?.[0];
}
const result = Array.from(
group(arr, getName).values(),
n => max(n, m => -m.price)
);
const prefixes = ['Inscribed', 'Autographed', 'Exalted', 'Corrupted'];
const prefixExpression = new RegExp(`^(${prefixes.join('|')})`, 'gi');
const items = [
{ name: 'Corrupted Demon Eater', price: '3215.00', inStock: 1 },
{ name: 'Exalted Demon Eater', price: '1530.00', inStock: 1 },
{ name: 'Demon Eater', price: '2900.00', inStock: 1 },
{ name: 'Whalehook', price: '1000.00', inStock: 1 },
{ name: 'Whalehook', price: '590.00', inStock: 1 },
{ name: 'Whalehook', price: '259.20', inStock: 1 },
{ name: 'Whalehook', price: '259.15', inStock: 1 },
{ name: 'Autographed Whalehook', price: '243.00', inStock: 1 },
{ name: 'Autographed Whalehook', price: '344.00', inStock: 1 },
{ name: 'Autographed Whalehook', price: '199.00', inStock: 1 },
{ name: 'Inscribed Whalehook', price: '355.00', inStock: 1 },
{ name: 'Inscribed Whalehook', price: '655.00', inStock: 1 },
{ name: 'Inscribed Whalehook', price: '5555.00', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '345.00', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '96.18', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '95.00', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '266.71', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '85.00', inStock: 1 }
];
const getCheapest = items => {
const store = items.reduce((accumulator, item) => {
const type = item.name.replace(prefixExpression, '').trim();
if (!accumulator.has(type)) {
accumulator.set(type, []);
}
accumulator.get(type).push(item);
return accumulator;
}, new Map());
const cheapest = store.values().reduce((accumulator, items) => {
const minPrice = Math.min(...items.map(item => parseFloat(item.price)));
const item = items.find(item => parseFloat(item.price) === minPrice);
accumulator.push(item);
return accumulator;
}, []);
return cheapest;
};
getCheapest(items);
/*
[
{ name: 'Exalted Demon Eater', price: '1530.00', inStock: 1 },
{ name: 'Autographed Whalehook', price: '199.00', inStock: 1 },
{ name: 'Inscribed Sylvan Cascade', price: '85.00', inStock: 1 }
]
*/
// Здесь структура сгруппированная по названию
const values = _.groupBy(data, 'name');
// Здесь структура сгруппированная по названию, и содержащая только самый дешевый вариант
const cheapItemsMap = _.mapValues(values, items => _.sortBy(items, 'price').reverse()[0]);
// Если нужен массив
const cheapItemsList = Object.values(cheapItemsMap );