@beefront17

Как сгруппировать свойства объекта?

Есть объект:

const obj = {
	12345: 1,
	12346: 2,
	12356: 1,
	12357: 1,
	12360: 1,
};

Надо просуммировать свойства, ключи которых имеют последовательные значения, в качестве нового ключа берётся первый ключ последовательности:

const obj = {
	12345: 3,
	12356: 2,
	12360: 1,
};
  • Вопрос задан
  • 259 просмотров
Решения вопроса 3
0xD34F
@0xD34F Куратор тега JavaScript
Object.fromEntries(Object
  .entries(obj)
  .sort((a, b) => a[0] - b[0])
  .reduce((acc, [ k, v ], i, a) => (
    i && k - a[~-i][0] === 1 || acc.push([ k, 0 ]),
    acc[~-acc.length][1] += v,
    acc
  ), [])
)
Ответ написан
sergiks
@sergiks Куратор тега JavaScript
♬♬
function groupProps(obj) {
    const sums = {};
    const result = {};
    
    for (let p in obj) {
      const key = p.substring(0, 4); // группируем по первым 4 символам
      if (!sums.hasOwnProperty(key)) {
        sums[key] = 0;
        result[p] = 0;
      }
      sums[key] += obj[p];
    }
    
    for (let p in result) {
      const key = p.substring(0, 4);
      result[p] = sums[key];
    }
    
    return result;
  }

  groupProps(obj) // {"12345":3,"12356":2,"12360":1}
Ответ написан
zendor
@zendor
Вдогонку:
Object.entries(obj).reduce((a, [k, v]) => {
  const ss = k.slice(0, -1);
  if (!a.ref[ss]) a.ref[ss] = k;
  a.res[a.ref[ss]] = ~~a.res[a.ref[ss]] + v;
  return a;
}, {ref: {}, res: {}}).res;
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
delphinpro
@delphinpro Куратор тега JavaScript
frontend developer
Накину еще вариантик с комментариями

// Исходный объект
const obj: {
    12345: 1,
    12346: 2,
    12356: 1,
    12357: 1,
    12360: 1,
}

// Результат
let result = {};

// Делаем из объекта массив, пригодный для преобразования в объект Map
const mapableArray = Object.entries(this.obj);

// Меняем местами ключи и значения
const mapableReversedArray = mapableArray.map(kv => [kv[1], kv[0]]);

// Создаем объект Map из обращенного массива
// При это дубликаты ключей будут перезаписаны и станут уникальными
const map = new Map(mapableReversedArray);

// Осталось только собрать целевой объект
map.forEach(function(value, key) { result[key] = value; });

// И использовать результат      
console.log(result);


Ну и этот же вариант в краткой записи

let result = {};
(new Map(Object.entries(this.obj).map(kv => [kv[1], kv[0]])))
    .forEach(function(value, key) { result[key] = value; });

console.log(result);


Или используя редьюсер

let result = Array.from(
    (new Map(Object.entries(this.obj).map(kv => [kv[1], kv[0]])))
).reduce((acc, v) => { acc[v[1]] = v[0]; return acc; }, {});


Но тут мы уже тоже начинаем смахивать на обфускатор. Ну нафиг такой код =))

В общем суть: поменять местами ключи и значения, запихнуть объект в Map, чтобы уникализировать значения (которые стали ключами), потом собрать все обратно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы