Показать сообщение отдельно
  #1 (permalink)  
Старый 01.08.2020, 08:56
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 571

Ускорите код?
Уважаемые знатоки, возможно ли ускорить функцию groupBy хотя бы в 1,5 раза (для node.js)?
/**
 * Group items by field
 *
 * items = [
 *  {id: 1, name: 'A', val: 1, smth: true},
 *  {id: 2, name: 'B', val: 2, ...},
 *  {id: 3, name: 'A', val: 3, ...},
 *  {id: 4, name: 'B', val: 4, ...},
 *  {id: 5, name: 'A', val: 5, ...}
 * ]
 *
 * groupBy(items, 'name', ['val', ...]) =
 *   [
 *     {
 *       groupField: 'name',
 *       groupValue: 'A',
 *
 *       // Items of the group
 *       items: [{id: 1, name: 'A', val: 1, , smth: true}, {id: 3, name: 'A', val: 3}, {id: 5, name: 'A', val: 5}],
 *
 *       // Values of first item
 *       id: 1,
 *       smth: true,
 *       ...
 *
 *       // Summed values
 *       val: 9,
 *       ...
 *     }, {
 *       groupField: 'name',
 *       groupValue: 'B',
 *       items: [{id: 2, name: 'B', val: 2}, {id: 4, name: 'B', val: 4}],
 *       id: 2,
 *       val: 6,
 *       ...
 *     }
 *   ]
 *
 * @param items - Array<any> - items array
 * @param field - string - field name
 * @param sumFields - Array<string> - array with names of fields which should be summed
 * @returns Array<any>
 */
function groupBy(items, field, sumFields = []) {
    const groupsMap = {};

    for (let i = 0; i < items.length; i++) {
        const item = items[i];
        const groupValue = item[field];
        let group = groupsMap[groupValue];

        if (!group) {
            group = {items: [], groupField: field, groupValue: groupValue, ...item};
            groupsMap[groupValue] = group;
        }

        // Add values which should be summed
        for (let j = 0; j < sumFields.length; j++) {
            const fieldName = sumFields[j];
            const sumValue = item[fieldName];

            if (sumValue) {
                group[fieldName] += sumValue;
            }
        }

        group.items.push(item);
    }

    return Object.keys(groupsMap).map(key => groupsMap[key]);
}

function generateData(amount) {
    return Array.from({length: amount}, (v, i) => {
        return {
            id: i,
            group: String.fromCharCode(Math.floor(Math.random() * 25) + 65),
            string: Math.random().toString(36).substring(2),
            number: Math.random() * 100,
            number2: Math.random() * 1000,
            null: null,
            undefined: undefined,
            boolean: true
        }
    })
}

const data = generateData(100000)
console.time('Groupping')
grouped = groupBy(data, 'group', ['number', 'number2'])
console.timeEnd('Groupping')

Последний раз редактировалось Shitbox2, 02.08.2020 в 00:20.
Ответить с цитированием