Подсчитывать по значению в массиве объектов в javascript с использованием lodash

У меня есть следующий массив объектов:

var input_array = [{
    role_name: 'Full Stack Developer',
    position_id: 'b0f00e68-5adc-4209-aec2-9c4962550ab1',
    email_address: '[email protected]',
    application_id: '1dd45634-c283-4a96-a28a-d8a63c418329',
    state: 'qualified',
    closing_date: '2018-10-28 06:30:00' },
{
    role_name: 'Delivery Representative',
    position_id: '090276f0-3fca-4b2a-85ed-697d21c405a0',
    email_address: '[email protected]',
    application_id: 'aa7fe2dd-b141-4c64-8350-a1d57bfaa502',
    state: 'interview',
    closing_date: '2018-10-28 06:30:00' },
{
    role_name: 'Delivery Representative',
    position_id: '12345678-5adc-4209-aec2-9c4962550ab1',
    email_address: '[email protected]',
    application_id: '166da0ac-aaf1-400d-9a62-e37962f66653',
    state: 'interview',
    closing_date: '2018-10-28 06:30:00' },
{
    role_name: 'Delivery Representative',
    position_id: '090276f0-3fca-4b2a-85ed-697d21c405a0',
    email_address: '[email protected]',
    application_id: 'da09a617-8e82-43c0-b1ea-725110a2c4cb',
    state: 'interview',
    closing_date: '2018-10-28 06:30:00' },
{
    role_name: 'Delivery Representative',
    position_id: '12345678-5adc-4209-aec2-9c4962550ab1',
    email_address: '[email protected]',
    application_id: '1d55a51a-ecd1-43ea-9cf4-fed101dbebda',
    state: 'offer',
    closing_date: '2018-10-28 06:30:00' },
{
    role_name: 'Micro Space Planner',
    position_id: 'fe30930f-7d9f-4953-8939-6d9924462b2b',
    email_address: '[email protected]',
    application_id: '293bd084-64f0-4c83-9b5d-aa304e44f066',
    state: 'screening',
    closing_date: '2018-10-28 06:30:00' },
{
    role_name: 'Delivery Representative',
    position_id: '12345678-5adc-4209-aec2-9c4962550ab1',
    email_address: '[email protected]',
    application_id: '2adc5236-989d-49f2-ab3e-cb7e42798b77',
    state: 'qualified',
    closing_date: '2018-10-28 06:30:00' },
{
    role_name: 'Micro Space Planner',
    position_id: 'fe30930f-7d9f-4953-8939-6d9924462b2b',
    email_address: '[email protected]',
    application_id: '293bd084-64f0-4c83-9b5d-aa304e44f066',
    state: 'screening',
    closing_date: '2018-10-28 06:30:00' },
{
    role_name: 'Delivery Representative',
    position_id: '12345678-5adc-4209-aec2-9c4962550ab1',
    email_address: '[email protected]',
    application_id: '2adc5236-989d-49f2-ab3e-cb7e42798b77',
    state: 'qualified',
    closing_date: '2018-10-28 06:30:00' }]

Я хочу считать объект с государством как предложение и собеседование, соответствующее каждой позиции. Я использую библиотеку npm lodash.

Я проверил несколько вопросов по SO о группе и подсчитал с помощью фильтра, но в моем случае идентификатор позиции является динамическим. Поэтому я не могу установить конкретное значение position_id, используя которое я могу группировать объекты.

например position_id как '12345678-5adc-4209-aec2-8b3962550ce7' содержит 1 предложение и 1 интервью

Ожидаемый результат:

{
    role_name: 'Delivery Representative',
    position_id: '12345678-5adc-4209-aec2-9c4962550ab1',
    email_address: '[email protected]',
    offer_count: 1,
    interview_count: 1
},
{
    role_name: 'Micro Space Planner',
    position_id: 'fe30930f-7d9f-4953-8939-6d9924462b2b',
    email_address: '[email protected]',
    offer_count: 0,
    interview_count:0
},
{
    role_name: 'Delivery Representative',
    position_id: '090276f0-3fca-4b2a-85ed-697d21c405a0',
    email_address: '[email protected]',
    offer_count: 0,
    interview_count:2
}

Итак, второй пример кода - это ваш ожидаемый результат?

Jared Smith 25.10.2018 14:23

да, второй для ожидаемого результата

Deep Kakkar 25.10.2018 14:24
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
271
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете использовать комбинацию reduce и map, либо родную версию JS, либо версию lodash. Во-первых, уменьшите количество ячеек записей по идентификатору позиции, затем вы сопоставляете записи объекта, чтобы получить нужный массив.

Object.entries(input_arr.reduce((acc, item) => {
  if (!acc[item.position_id]) {
    acc[item.position_id] = {
      interview_count: 0,
      offer_count: 0,
      email_address: item.email_address,
      role_name: item.role_name
    };
  }

  if (item.state === 'interview') acc[item.position_id].interview_count += 1;
  if (item.state === 'offer') acc[item.position_id].offer_count += 1;
  return acc;
}, {})).map(([position_id, {email_address, interview_count, offer_count, role_name}]) => {
  return {
    position_id,
    email_address,
    interview_count,
    offer_count,
    role_name
  };
});

Вот рабочий пример

Переменная arr означает input_array? а что там Object.entries? и Будет ли полный код находиться в функции, и мне придется вызывать функцию, используя параметры как input_array? не могли бы вы соответствующим образом изменить код?

Deep Kakkar 25.10.2018 14:31

@ Глубоко да на первый вопрос. Запись MDN в Object.entries

Jared Smith 25.10.2018 14:33

Я признателен, если вы можете сделать jsfiddle для этой проблемы

Deep Kakkar 25.10.2018 14:34

@ Глубоко сделано. Смотрите мой обновленный ответ. Вы можете запустить его и просмотреть массив результатов в консоли.

Jared Smith 25.10.2018 14:37

Хорошо, я проверю. Спасибо за ваши усилия.

Deep Kakkar 25.10.2018 14:39

Вы можете уменьшить исходный массив до нового хеш-объекта, чтобы содержать карту позиций и подсчитывать состояния входного массива.

let interviews = input_array.reduce(function(acc, cur) {  // go over every applicant
    if (!acc[cur.position_id]) {
        acc[cur.position_id] = {      //set initial object if the job is new
            role_name: cur.role_name,
            ...,
            offer_count: 0,
            interview_count:0
        }
    }

    if (cur.state === "offer") {
        acc[cur.position_id].offer_count++;
    } else if (cur.state === "interview") {
        acc[cur.position_id].interview_count++;
    }

    return acc;
}, {});

Reduce - это собственный метод массива JS, поэтому вам фактически не нужно использовать lodash или какие-либо внешние библиотеки для этого вычисления.

Не соответствует желаемому результату.

Jared Smith 25.10.2018 14:29

Это правильно, хотя вы можете легко преобразовать хэш-объект в массив с помощью arr = Object.values(obj), я все же рекомендую сохранить хеш-формат, поскольку это лучший способ сохранить список уникальных job_ids. более доступный.

Rodik 25.10.2018 14:32
Ответ принят как подходящий

Вы можете использовать функцию reduce для группировки объектов по id и функцию Object.values для извлечения сгруппированных объектов.

let input_array = [{    role_name: 'Full Stack Developer',    position_id: 'b0f00e68-5adc-4209-aec2-9c4962550ab1',    email_address: '[email protected]',    application_id: '1dd45634-c283-4a96-a28a-d8a63c418329',    state: 'qualified',    closing_date: '2018-10-28 06:30:00' },{    role_name: 'Delivery Representative',    position_id: '090276f0-3fca-4b2a-85ed-697d21c405a0',    email_address: '[email protected]',    application_id: 'aa7fe2dd-b141-4c64-8350-a1d57bfaa502',    state: 'interview',    closing_date: '2018-10-28 06:30:00' },{    role_name: 'Delivery Representative',    position_id: '12345678-5adc-4209-aec2-9c4962550ab1',    email_address: '[email protected]',    application_id: '166da0ac-aaf1-400d-9a62-e37962f66653',    state: 'interview',    closing_date: '2018-10-28 06:30:00' },{    role_name: 'Delivery Representative',    position_id: '090276f0-3fca-4b2a-85ed-697d21c405a0',    email_address: '[email protected]',    application_id: 'da09a617-8e82-43c0-b1ea-725110a2c4cb',    state: 'interview',    closing_date: '2018-10-28 06:30:00' },{    role_name: 'Delivery Representative',    position_id: '12345678-5adc-4209-aec2-9c4962550ab1',    email_address: '[email protected]',    application_id: '1d55a51a-ecd1-43ea-9cf4-fed101dbebda',    state: 'offer',    closing_date: '2018-10-28 06:30:00' },{    role_name: 'Micro Space Planner',    position_id: 'fe30930f-7d9f-4953-8939-6d9924462b2b',    email_address: '[email protected]',    application_id: '293bd084-64f0-4c83-9b5d-aa304e44f066',    state: 'screening',    closing_date: '2018-10-28 06:30:00' },{    role_name: 'Delivery Representative',    position_id: '12345678-5adc-4209-aec2-9c4962550ab1',    email_address: '[email protected]',    application_id: '2adc5236-989d-49f2-ab3e-cb7e42798b77',    state: 'qualified',    closing_date: '2018-10-28 06:30:00' },{    role_name: 'Micro Space Planner',    position_id: 'fe30930f-7d9f-4953-8939-6d9924462b2b',    email_address: '[email protected]',    application_id: '293bd084-64f0-4c83-9b5d-aa304e44f066',    state: 'screening',    closing_date: '2018-10-28 06:30:00' },{    role_name: 'Delivery Representative',    position_id: '12345678-5adc-4209-aec2-9c4962550ab1',    email_address: '[email protected]',    application_id: '2adc5236-989d-49f2-ab3e-cb7e42798b77',    state: 'qualified',    closing_date: '2018-10-28 06:30:00' }],
    result = Object.values(input_array.reduce((a, {state, role_name, position_id, email_address}) => { 
      a[position_id] = (a[position_id] || {role_name, position_id, email_address, offer_count: 0, interview_count: 0});
      a[position_id].offer_count += (state === 'offer');
      a[position_id].interview_count += (state === 'interview');
      return a;
    }, Object.create(null)));

console.info(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Вы можете сделать это примерно так, без lodash и через reduce, Object.assign и Object.values:

var data = [{ role_name: 'Full Stack Developer', position_id: 'b0f00e68-5adc-4209-aec2-9c4962550ab1', email_address: '[email protected]', application_id: '1dd45634-c283-4a96-a28a-d8a63c418329', state: 'qualified', closing_date: '2018-10-28 06:30:00' }, { role_name: 'Delivery Representative', position_id: '090276f0-3fca-4b2a-85ed-697d21c405a0', email_address: '[email protected]', application_id: 'aa7fe2dd-b141-4c64-8350-a1d57bfaa502', state: 'interview', closing_date: '2018-10-28 06:30:00' }, { role_name: 'Delivery Representative', position_id: '12345678-5adc-4209-aec2-9c4962550ab1', email_address: '[email protected]', application_id: '166da0ac-aaf1-400d-9a62-e37962f66653', state: 'interview', closing_date: '2018-10-28 06:30:00' }, { role_name: 'Delivery Representative', position_id: '090276f0-3fca-4b2a-85ed-697d21c405a0', email_address: '[email protected]', application_id: 'da09a617-8e82-43c0-b1ea-725110a2c4cb', state: 'interview', closing_date: '2018-10-28 06:30:00' }, { role_name: 'Delivery Representative', position_id: '12345678-5adc-4209-aec2-9c4962550ab1', email_address: '[email protected]', application_id: '1d55a51a-ecd1-43ea-9cf4-fed101dbebda', state: 'offer', closing_date: '2018-10-28 06:30:00' }, { role_name: 'Micro Space Planner', position_id: 'fe30930f-7d9f-4953-8939-6d9924462b2b', email_address: '[email protected]', application_id: '293bd084-64f0-4c83-9b5d-aa304e44f066', state: 'screening', closing_date: '2018-10-28 06:30:00' }, { role_name: 'Delivery Representative', position_id: '12345678-5adc-4209-aec2-9c4962550ab1', email_address: '[email protected]', application_id: '2adc5236-989d-49f2-ab3e-cb7e42798b77', state: 'qualified', closing_date: '2018-10-28 06:30:00' }, { role_name: 'Micro Space Planner', position_id: 'fe30930f-7d9f-4953-8939-6d9924462b2b', email_address: '[email protected]', application_id: '293bd084-64f0-4c83-9b5d-aa304e44f066', state: 'screening', closing_date: '2018-10-28 06:30:00' }, { role_name: 'Delivery Representative', position_id: '12345678-5adc-4209-aec2-9c4962550ab1', email_address: '[email protected]', application_id: '2adc5236-989d-49f2-ab3e-cb7e42798b77', state: 'qualified', closing_date: '2018-10-28 06:30:00' }]

const combine = (r = {offer_count: 0, interview_count: 0}, c) => {
   r.offer_count += c.state ==='offer'
   r.interview_count += c.state === 'interview'
   let {application_id, state, closing_date, ...rest} = c
   return Object.assign(r, rest)
}
const countEm = d => Object.values(d.reduce((r,c) => (r[c.position_id] = combine(r[c.position_id], c), r), {}))

console.info(countEm(data))

Другие вопросы по теме