Получить последнее значение непрерывно повторяющегося свойства в объекте

У меня есть этот массив сделки:

const transactions = [
  {
    service: 'Some Text Assignment #1',
    phase: 'Assignment'
  },
  {
    service: 'Some Text Processing #1',
    phase: 'Processing'
  },
  {
    service: 'Some Text Processing #2',
    phase: 'Processing'
  },
  {
    service: 'Some Text Issue Constancy #1',
    phase: 'Issue Constancy'
  },
  {
    service: 'Some Text Quality Control #1',
    phase: 'Quality Control'
  },
  {
    service: 'Some Text Signature and stamp #1',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Signature and stamp #2',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Signature and stamp #3',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Processing #3',
    phase: 'Processing'
  },
  {
    service: 'Some Text Processing #4',
    phase: 'Processing'
  },
  {
    service: 'Some Text Signature and stamp #4',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Signature and stamp #5',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Approved #1',
    phase: 'Approved'
  }
];

Мне нужно получить значения, сгруппированные по phase, но с определенным условием:

нужен последнее значение из фазы, которые непрерывны в пределах одинаковое значение фазы.

Я хочу получить что-то вроде этого:

[
  {
    service: 'Some Text Assignment #1',
    phase: 'Assignment'
  },
  {
    service: 'Some Text Processing #2',
    phase: 'Processing'
  },
  {
    service: 'Some Text Issue Constancy #1',
    phase: 'Issue Constancy'
  },
  {
    service: 'Some Text Quality Control #1',
    phase: 'Quality Control'
  },
  {
    service: 'Some Text Signature and stamp #3',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Processing #4',
    phase: 'Processing'
  },
  {
    service: 'Some Text Signature and stamp #5',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Approved #1',
    phase: 'Approved'
  }
]

Я пробовал это:

transactions.reduce((acc, value) => {
  acc[value.phase] = value;
  return acc;
}, {});

Но я получаю последнее значение каждого phase. Я подумал об использовании Maps или Sets. Некоторые идеи?

Поведение ключевого слова "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
0
57
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Вы пытаетесь решить почти правильно, но вы должны проверить последний вставленный объект, а не любой вставленный объект.

const transactions = [
  {
    service: 'Some Text Assignment #1',
    phase: 'Assignment'
  },
  {
    service: 'Some Text Processing #1',
    phase: 'Processing'
  },
  {
    service: 'Some Text Processing #2',
    phase: 'Processing'
  },
  {
    service: 'Some Text Issue Constancy #1',
    phase: 'Issue Constancy'
  },
  {
    service: 'Some Text Quality Control #1',
    phase: 'Quality Control'
  },
  {
    service: 'Some Text Signature and stamp #1',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Signature and stamp #2',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Signature and stamp #3',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Processing #3',
    phase: 'Processing'
  },
  {
    service: 'Some Text Processing #4',
    phase: 'Processing'
  },
  {
    service: 'Some Text Signature and stamp #4',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Signature and stamp #5',
    phase: 'Signature and stamp'
  },
  {
    service: 'Some Text Approved #1',
    phase: 'Approved'
  }
];

let out = transactions.reduce((acc, value) => {
  let last = acc.length && acc[acc.length - 1];
  if (last && last.phase === value.phase)
    last.service = value.service;
  else
    acc.push(value);
  return acc;
}, []);

console.info(out);

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

const transactions = [{"service":"Some Text Assignment #1","phase":"Assignment"},{"service":"Some Text Processing #1","phase":"Processing"},{"service":"Some Text Processing #2","phase":"Processing"},{"service":"Some Text Issue Constancy #1","phase":"Issue Constancy"},{"service":"Some Text Quality Control #1","phase":"Quality Control"},{"service":"Some Text Signature and stamp #1","phase":"Signature and stamp"},{"service":"Some Text Signature and stamp #2","phase":"Signature and stamp"},{"service":"Some Text Signature and stamp #3","phase":"Signature and stamp"},{"service":"Some Text Processing #3","phase":"Processing"},{"service":"Some Text Processing #4","phase":"Processing"},{"service":"Some Text Signature and stamp #4","phase":"Signature and stamp"},{"service":"Some Text Signature and stamp #5","phase":"Signature and stamp"},{"service":"Some Text Approved #1","phase":"Approved"}]


let final = transactions.reduce((op,inp,index)=>{
  if ( index + 1 ===  transactions.length){
    if (transactions[index-1].phase !== inp.phase){
      op.push(inp)
    }
  }
  else if (transactions[index+1].phase !== inp.phase){
    op.push(inp)
  }
  return op
},[])

console.info(final)

Сгруппируйте соседние элементы с помощью Array.reduce(), затем сопоставьте и возьмите последний элемент в каждой группе:

const transactions = [{"service":"Some Text Assignment #1","phase":"Assignment"},{"service":"Some Text Processing #1","phase":"Processing"},{"service":"Some Text Processing #2","phase":"Processing"},{"service":"Some Text Issue Constancy #1","phase":"Issue Constancy"},{"service":"Some Text Quality Control #1","phase":"Quality Control"},{"service":"Some Text Signature and stamp #1","phase":"Signature and stamp"},{"service":"Some Text Signature and stamp #2","phase":"Signature and stamp"},{"service":"Some Text Signature and stamp #3","phase":"Signature and stamp"},{"service":"Some Text Processing #3","phase":"Processing"},{"service":"Some Text Processing #4","phase":"Processing"},{"service":"Some Text Signature and stamp #4","phase":"Signature and stamp"},{"service":"Some Text Signature and stamp #5","phase":"Signature and stamp"},{"service":"Some Text Approved #1","phase":"Approved"}]

const result =
  transactions.reduce((r, o, i, arr) => {
    if (!i || o.phase !== arr[i - 1].phase) r.push([]);
    
    r[r.length - 1].push(o);
  
    return r;
  }, [])
  .map(arr => arr[arr.length - 1]);
  
console.info(result);

Используйте Массив.уменьшить следующим образом

  • Поддерживать переменную, которая хранит последнюю посещенную фазу
  • Для каждого элемента проверьте, совпадает ли фаза со значением, хранящимся в фазовой переменной.
  • Если значение отличается или не определено (для первого значения), поместите значение в массив и установите значение фазы в переменной фазы.
  • иначе обновить последнее значение в результирующем массиве с элементом

const transactions = [{"service":"Some Text Assignment #1","phase":"Assignment"},{"service":"Some Text Processing #1","phase":"Processing"},{"service":"Some Text Processing #2","phase":"Processing"},{"service":"Some Text Issue Constancy #1","phase":"Issue Constancy"},{"service":"Some Text Quality Control #1","phase":"Quality Control"},{"service":"Some Text Signature and stamp #1","phase":"Signature and stamp"},{"service":"Some Text Signature and stamp #2","phase":"Signature and stamp"},{"service":"Some Text Signature and stamp #3","phase":"Signature and stamp"},{"service":"Some Text Processing #3","phase":"Processing"},{"service":"Some Text Processing #4","phase":"Processing"},{"service":"Some Text Signature and stamp #4","phase":"Signature and stamp"},{"service":"Some Text Signature and stamp #5","phase":"Signature and stamp"},{"service":"Some Text Approved #1","phase":"Approved"}];

let phase;
const result = transactions.reduce((a,c) => {
  if (phase && c.phase == phase) a[a.length-1] = c;
  else { a.push(c); phase = c.phase;}
  return a;
}, []);
console.info(result);
Ответ принят как подходящий

Другими словами: вы просто хотите отфильтровать повторяющиеся фазы:

  const result =  [...transactions]
    .reverse()
    .filter((el, i, arr) => !i || el.phase !== arr[i - 1].phase)
    .reverse();

Очень просто и логично!

robe007 07.06.2019 18:16

Вы можете добавить элемент в вывод, если следующий элемент в массиве не имеет того же phase, что и текущий элемент.

const transactions=[{service:"Some Text Assignment #1",phase:"Assignment"},{service:"Some Text Processing #1",phase:"Processing"},{service:"Some Text Processing #2",phase:"Processing"},{service:"Some Text Issue Constancy #1",phase:"Issue Constancy"},{service:"Some Text Quality Control #1",phase:"Quality Control"},{service:"Some Text Signature and stamp #1",phase:"Signature and stamp"},{service:"Some Text Signature and stamp #2",phase:"Signature and stamp"},{service:"Some Text Signature and stamp #3",phase:"Signature and stamp"},{service:"Some Text Processing #3",phase:"Processing"},{service:"Some Text Processing #4",phase:"Processing"},{service:"Some Text Signature and stamp #4",phase:"Signature and stamp"},{service:"Some Text Signature and stamp #5",phase:"Signature and stamp"},{service:"Some Text Approved #1",phase:"Approved"}];

const output = []

transactions.forEach((o, i) => {
  const next = transactions[i + 1] || {};
  if (next.phase !== o.phase)
    output.push(o)
})

console.info(output)

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