подсчитать повторный массив свойства объекта для создания нового массива - PullRequest
3 голосов
/ 02 апреля 2019

У меня есть этот массив объектов

[{
    tag: 'james'
  },
  {
    tag: 'james'
  },
  {
    tag: 'john'
  }
]

Как мне посчитать и создать новый массив, как показано ниже?

[{
  tag: 'james',
  count: 2
}, {
  tag: 'john',
  count: 1
}]

Моя попытка использовать уменьшение произведенного объекта, а не массива объекта.

const arr = [{tag: 'james'},{tag: 'james'},{tag: 'john'}];
let newArr = arr.reduce((accum, arr) => {
  accum[arr.tag] = ++accum[arr.tag] || 1
  return accum
}, {})

console.log(newArr)

Ответы [ 6 ]

3 голосов
/ 02 апреля 2019

Создайте объект вместо числа и, наконец, получите эти значения из объекта, используя метод Object.values.

// just extract values from the object as an array
let res = Object.values(arr.reduce((accum, o) => {
  // initialize object if not defined already
  accum[o.tag] = accum[o.tag] || { ...o, count: 0  }
  // increment count property
  accum[o.tag].count++;
  return accum
}, {}))

let arr = [{tag: 'james'},{tag: 'james'},{tag: 'john'}]

let res = Object.values(arr.reduce((accum, o) => {
  accum[o.tag] = accum[o.tag] || { ...o, count: 0 }
  accum[o.tag].count++;
  return accum
}, {}))

console.log(res)

<ч /> Вы даже можете создать массив напрямую, используя дополнительную переменную для ссылки на объект / индекс.

// an object for keeping reference 
let ref = {};

let res = arr.reduce((accum, o) => {
  // check reference already defined, if not define refernece and push to the array
  ref[o.tag] || accum.push(ref[o.tag] = { ...o, count: 0 })
  // update count using the refernece keeped in the object
  ref[o.tag].count++;
  return accum
}, []);

let arr = [{tag: 'james'},{tag: 'james'},{tag: 'john'}]

let ref = {};

let res = arr.reduce((accum, o) => {
  ref[o.tag] || accum.push(ref[o.tag] = { ...o, count: 0 })
  ref[o.tag].count++;
  return accum
}, []);

console.log(res)
2 голосов
/ 02 апреля 2019

Вы были почти у цели, но вам нужно вынуть ключ и значение из объекта и построить новый массив.

var array = [{ tag: 'jane' }, { tag: 'jane' }, { tag: 'john' }],
    result = Object
        .entries(
            array.reduce((accum, { tag }) => {
                accum[tag] = (accum[tag] || 0) + 1;
                return accum;
            }, {}))
        .map(([tag, count]) => ({ tag, count }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 02 апреля 2019
//simple approach using forEach method

let lists = [{tag: 'james'},{tag: 'james'},{tag: 'john'}]; 
const finalOutput = [];
const tempStore = {};

lists.forEach((list) => {
      tempStore[list.tag] = (tempStore[list.tag] == undefined) ? 1: tempStore[list.tag]+1;
      const index = finalOutput.findIndex(e => e.tag == list.tag);
      if(index > -1) {
        finalOutput[index] = {tag: list.tag, count: tempStore[list.tag]}
      }
      else 
        finalOutput.push({tag: list.tag, count: tempStore[list.tag]})
});

console.log(finalOutput);
0 голосов
/ 02 апреля 2019

Ваша интуиция была хорошей, и вы были довольно близки; Я предлагаю вам более общий ответ

const groupTags = data => field => Object.values(data.reduce((acc, o) =>
({...acc,
  [o[field]]: {
    [field]: o[field],
    count: acc[o[field]] ? acc[o[field]].count + 1 : 1 
  }
}), {}))

Вы можете использовать его как

groupTags(data)("tag")
0 голосов
/ 02 апреля 2019

Более простой код будет:

const arr = [{
    tag: 'james'
  },
  {
    tag: 'james'
  },
  {
    tag: 'john'
  },
  {
    tag: 'lewis'
  },
  {
    tag: 'john'
  }
]

const counts = arr.reduce((acc, cv) => {
  const val = acc.find(t => t.tag == cv.tag)
  if (val) {
    val.count++
    acc.push(val)
    return acc
  }
  cv.count = 1
  acc.push(cv)
  return acc
}, [])

console.log(counts)
0 голосов
/ 02 апреля 2019

Первый тест, если объект не существует - если его нет, создайте его. Затем добавьте в аккумулятор. Также обратите внимание, что вам нужен массив, поэтому используйте [], а не {} для значения аккумулятора:

const data = [{
    tag: 'james'
  },
  {
    tag: 'james'
  },
  {
    tag: 'john'
  }
];

const grouped = data.reduce((acc, { tag }) => {
  if (!acc.some(e => e.tag == tag)) {
    acc.push({ tag, count: 0 });
  }
  acc.find(e => e.tag == tag).count++;
  return acc;
}, []);

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: auto; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...