Уменьшить массив объектов в javascript - PullRequest
2 голосов
/ 27 января 2020

У меня есть массив объектов в javascript, который я хочу уменьшить. Смотрите код ниже. сообщение с 6 или более цифрами проверено, меньшее количество не проверено. Я группирую их по группам.

const myArray = [
  { group: 'groupA', message: 'Text without a number', sl: '1A' },
  { group: 'groupA', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupB', message: 'Text without a number', sl: '1A' },
  { group: 'groupA', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupB', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupC', message: 'Text without a number', sl: '1B' },
  { group: 'groupD', message: 'Text with a number Tick0127866', sl: '1B' },
  { group: 'groupC', message: 'Text without a number', sl: '1A' }
];

output = myArray.reduce((acc, line) => {
  let yes = 0;
  let no = 0;

  line.message.match(/\d{6,}/) ? yes++ : no++;

  acc[line.group] = acc[line.group] || {};
  acc[line.group].verified = (acc[line.group].verified || 0) + yes;
  acc[line.group].unverified = (acc[line.group].unverified || 0) + no;
  return acc;
}, {});

console.log('output', output);

Однако я хотел бы, чтобы вывод также представлял собой массив объектов, таких как:

[
  { group: 'groupA', verified: 2, unverified: 1 },
  { group: 'groupB', verified: 1, unverified: 1 },
  { group: 'groupC', verified: 0, unverified: 2 },
  { group: 'groupD', verified: 1, unverified: 0 }
]

Как бы я это сделал?

Ответы [ 6 ]

4 голосов
/ 27 января 2020

Используйте массив в качестве начального значения вашего аккумулятора и внутри .reduce, используйте findIndex, чтобы проверить текущую группу, если она найдена, обновите значения verified и unverified, в противном случае вставьте новое:

const myArray = [
  { group: "groupA", message: "Text without a number", sl: "1A" },
  { group: "groupA", message: "Text with a number WO5467829", sl: "1A" },
  { group: "groupB", message: "Text without a number", sl: "1A" },
  { group: "groupA", message: "Text with a number WO5467829", sl: "1A" },
  { group: "groupB", message: "Text with a number WO5467829", sl: "1A" },
  { group: "groupC", message: "Text without a number", sl: "1B" },
  { group: "groupD", message: "Text with a number Tick0127866", sl: "1B" },
  { group: "groupC", message: "Text without a number", sl: "1A" }
];

output = myArray.reduce((acc, line) => {
  let yes = 0;
  let no = 0;

  line.message.match(/\d{6,}/) ? yes++ : no++;

  // check if you have the group in the accumulator
  const ndx = acc.findIndex(e => e.group === line.group);

  // if you have it, manipulate verified and unverified
  if (ndx > -1) {
    acc[ndx].verified = (acc[ndx].verified || 0) + yes;
    acc[ndx].unverified = (acc[ndx].unverified || 0) + no;
  } else {
    // insert a new entry instead
    acc.push({
      group: line.group,
      verified: yes,
      unverified: no
    });
  }

  return acc;
}, []); // use an array as the initial value of the accumulator

console.log(output);
3 голосов
/ 28 января 2020

Я не мог удержаться от того, чтобы немного поменять код. Это сказал. что я сделал:

  • инициируем аккумулятор с массивом ([])
  • pu sh группой в массив, если он еще не инициализирован
  • приращение verified или unverified в зависимости от того, провалился ли ваш тест

const myArray = [
  { group: "groupA", message: "Text without a number", sl: "1A" },
  { group: "groupA", message: "Text with a number WO5467829", sl: "1A" },
  { group: "groupB", message: "Text without a number", sl: "1A" },
  { group: "groupA", message: "Text with a number WO5467829", sl: "1A" },
  { group: "groupB", message: "Text with a number WO5467829", sl: "1A" },
  { group: "groupC", message: "Text without a number", sl: "1B" },
  { group: "groupD", message: "Text with a number Tick0127866", sl: "1B" },
  { group: "groupC", message: "Text without a number", sl: "1A" }
];

output = myArray.reduce((acc, line) => {
  if( acc.findIndex(e => e.group === line.group) === -1 ) {
  	acc.push({
      group: line.group,
      verified: 0,
      unverified: 0
    });
  }
  
  let group = acc.find(e => e.group === line.group);

  if( line.message.match(/\d{6,}/) )
  	group.verified++;
  else
  	group.unverified++;

  return acc;
}, []);

console.log(output);
3 голосов
/ 27 января 2020

Вы можете просто расширить свое решение / вывод, чтобы получить фактический требуемый вывод, используя Object.entries() или Object.keys(). Я собираюсь использовать Object.entries()

const myArray = [
  { group: 'groupA', message: 'Text without a number', sl: '1A' },
  { group: 'groupA', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupB', message: 'Text without a number', sl: '1A' },
  { group: 'groupA', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupB', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupC', message: 'Text without a number', sl: '1B' },
  { group: 'groupD', message: 'Text with a number Tick0127866', sl: '1B' },
  { group: 'groupC', message: 'Text without a number', sl: '1A' }
];

output = myArray.reduce((acc, line) => {
  let yes = 0;
  let no = 0;

  line.message.match(/\d{6,}/) ? yes++ : no++;

  acc[line.group] = acc[line.group] || {};
  acc[line.group].verified = (acc[line.group].verified || 0) + yes;
  acc[line.group].unverified = (acc[line.group].unverified || 0) + no;
  return acc;
}, {});

console.log('output', output);

const actualOutput = Object.entries(output).map(([group, value]) => ({group, ...value }));

console.log(actualOutput);
2 голосов
/ 27 января 2020

Вы можете использовать map() на Object.entries. Я также рефакторинг вашего кода в reduce метод

const myArray = [
  { group: 'groupA', message: 'Text without a number', sl: '1A' },
  { group: 'groupA', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupB', message: 'Text without a number', sl: '1A' },
  { group: 'groupA', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupB', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupC', message: 'Text without a number', sl: '1B' },
  { group: 'groupD', message: 'Text with a number Tick0127866', sl: '1B' },
  { group: 'groupC', message: 'Text without a number', sl: '1A' }
];

let output = myArray.reduce((acc, line) => {
  acc[line.group] = acc[line.group] || {verified: 0, unverified: 0};
  if(line.message.match(/\d{6,}/)){
    acc[line.group].verified++
  }
  else{
    acc[line.group].unverified++
  }

  return acc;
}, {});

output = Object.entries(output).map(([k, v]) => ({group: k, ...v}))

console.log('output', output);
1 голос
/ 27 января 2020

Используйте уменьшение в сочетании с проверкой регулярных выражений, например:

const myArray = [{
    group: 'groupA',
    message: 'Text without a number',
    sl: '1A'
  },
  {
    group: 'groupA',
    message: 'Text with a number WO5467829',
    sl: '1A'
  },
  {
    group: 'groupB',
    message: 'Text without a number',
    sl: '1A'
  },
  {
    group: 'groupA',
    message: 'Text with a number WO5467829',
    sl: '1A'
  },
  {
    group: 'groupB',
    message: 'Text with a number WO5467829',
    sl: '1A'
  },
  {
    group: 'groupC',
    message: 'Text without a number',
    sl: '1B'
  },
  {
    group: 'groupD',
    message: 'Text with a number Tick0127866',
    sl: '1B'
  },
  {
    group: 'groupC',
    message: 'Text without a number',
    sl: '1A'
  }
];

const numberRegex = /[0-9]{6}/;

const res = Object.values(myArray.reduce((acc, curr) => {
  const { group, message } = curr;
  const isPhoneVerified = numberRegex.test(message);

  if (!acc[group] && isPhoneVerified) {
    acc[group] = { group: group, verified: 1, unverified: 0 };
  } else if (!acc[group] && !isPhoneVerified) {
    acc[group] = { group: group, verified: 0, unverified: 1 };
  } else if (acc[group] && isPhoneVerified) {
    acc[group].verified += 1;
  } else if (acc[group] && !isPhoneVerified) {
    acc[group].unverified += 1;
  }

  return acc;

}, {}));

console.log(res);
1 голос
/ 27 января 2020

Положите group опору в ваш cc. Затем используйте функцию Object.values для возврата значений объекта.

const myArray = [
  { group: 'groupA', message: 'Text without a number', sl: '1A' },
  { group: 'groupA', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupB', message: 'Text without a number', sl: '1A' },
  { group: 'groupA', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupB', message: 'Text with a number WO5467829', sl: '1A' },
  { group: 'groupC', message: 'Text without a number', sl: '1B' },
  { group: 'groupD', message: 'Text with a number Tick0127866', sl: '1B' },
  { group: 'groupC', message: 'Text without a number', sl: '1A' }
];

output = myArray.reduce((acc, line) => {
  let yes = 0;
  let no = 0;

  line.message.match(/\d{6,}/) ? yes++ : no++;

  acc[line.group] = acc[line.group] || {};
  acc[line.group].group = line.group;
  acc[line.group].verified = (acc[line.group].verified || 0) + yes;
  acc[line.group].unverified = (acc[line.group].unverified || 0) + no;
  return acc;
}, {});

console.log('output', Object.values(output));
...