获取对象中连续重复属性的最后一个值

时间:2019-05-21 18:18:26

标签: javascript arrays json object grouping

我有这个数组 transactions

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的最后一个值。我曾经考虑过使用MapsSets。有想法吗?

6 个答案:

答案 0 :(得分:2)

如果数组中的下一个与当前项目不同的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.log(output)

答案 1 :(得分:1)

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.log(result);

答案 2 :(得分:1)

使用Array.reduce如下

  • 维护一个变量,该变量存储上次访问的阶段
  • 对于每个元素,检查相位是否与存储在相位变量中的值相同
  • 如果值不同或未定义(对于第一个值),则将值推送到数组中,并将phase的值设置为变量phase
  • else用item更新结果数组中的最后一个值

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.log(result);

答案 3 :(得分:1)

换句话说:您只想过滤出重复的阶段:

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

答案 4 :(得分:0)

您尝试的解决方案几乎是正确的,但是您应该检查最后插入的对象,而不是任何插入的对象。

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.log(out);

答案 5 :(得分:0)

您可以检查相邻的值,并在看到不匹配的阶段后添加

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.log(final)