根据条件在单个数组中合并顺序对象

时间:2019-06-17 13:12:29

标签: javascript arrays object reduce

我想根据条件将数据的顺序对象合并到数组中。我有一个路线数组,其中每个对象都是该行程的一部分。考虑以下示例:

旅行1:WALK - WALK - WALK - VEHICLE - WALK - VEHICLE - WALK ^ short transfer

旅行2:WALK - WALK - WALK - VEHICLE - WALK - WALK - VEHICLE - WALK - VEHICLE

旅行3:WALK - WALK - VEHICLE - WALK - WALK


我想做的是将WALK条腿依次(彼此紧接)合并为一条覆盖合并部分的WALK条腿,请参见下文:

旅行1:WALK - VEHICLE - WALK - VEHICLE - WALK ^ short transfer

旅行2:WALK - VEHICLE - WALK - VEHICLE - WALK - VEHICLE

旅行3:WALK - VEHICLE - WALK


每个腿对象看起来像这样:

{
    mode: 'WALK', // or VEHICLE
    to: { ... },
    from: { ... }
}

我尝试使用.reduce()并在其当前索引功能的帮助下将不同部分组合在一起,但没有成功。我什至不知道它是否是正确的功能。

const oldTrip = [
	{ mode: 'WALK' },
	{ mode: 'WALK' },
	{ mode: 'VEHICLE' },
	{ mode: 'VEHICLE' },
	{ mode: 'WALK' }
];

let previousWalk = false;
const newTrip = oldTrip.reduce((acc, cur, idx) => {
  if (cur.mode === 'VEHICLE') previousWalk = false;
  else {
    if (previousWalk) {
      
    }
    previousWalk = true;
  }
  return acc;
});

非常感谢您的帮助或朝着正确的方向前进!

5 个答案:

答案 0 :(得分:2)

Array#reduce将为您返回一个值。

使用Array#filter,而不是将最后一个迭代值与当前值进行比较。

const steps = [
  { mode: 'WALK' },
  { mode: 'WALK' },
  { mode: 'VEHICLE' },
  { mode: 'VEHICLE' },
  { mode: 'WALK' },
  { mode: 'VEHICLE' },
  { mode: 'VEHICLE' },
  { mode: 'VEHICLE' },
  { mode: 'WALK' },
  { mode: 'WALK' },
  { mode: 'VEHICLE' },
  { mode: 'VEHICLE' },
  { mode: 'WALK' }
];

console.log(

steps.filter((s, i, self) => (
  !self[i + 1]
    || s.mode === 'VEHICLE'
    || self[i + 1].mode !== s.mode
  ))

);

答案 1 :(得分:2)

我不是使用reduce()而是使用带有索引的filter(),幸运的是我们无法遇到这样的OutOfBound。仅当我们将“ WALK”作为当前元素时,才检查重复。我添加了第四个示例,以显示非行走重复不会被过滤。

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements  AfterViewInit {
  .....

  @ViewChild('productDetails', {read: ViewContainerRef}) entry: ViewContainerRef;

  ngAfterViewInit() {
    console.log('Values on ngAfterViewInit():');
    console.log("entry:", this.entry);
  }  

  .....
}

要对对象执行相同的操作,请执行以下操作:

function filterRepWalk(a) {
  return a.filter((v,i) => v != "WALK" || v != a[i-1]);
}

console.log(filterRepWalk(["WALK", "WALK", "WALK", "VEHICLE", "WALK",  "VEHICLE", "WALK"]));
console.log(filterRepWalk(["WALK", "WALK", "WALK", "VEHICLE", "WALK", "WALK", "VEHICLE", "WALK", "VEHICLE"]));
console.log(filterRepWalk(["WALK", "WALK", "VEHICLE", "WALK", "WALK"]));
console.log(filterRepWalk(["WALK", "WALK", "WALK", "VEHICLE", "WALK", "WALK", "VEHICLE", "WALK", "VEHICLE", "VEHICLE"]));

答案 2 :(得分:1)

您可以在Array.filter数组参数处进行解构,并获得如下所示的简洁解决方案:

let filter = (arr, str) => arr.filter((x,i,{[i-1]:k}) => x != str || x != k)

console.log(filter(["WALK", "WALK", "VEHICLE"], 'WALK'));
console.log(filter(["VEHICLE", "VEHICLE", "WALK"], 'VEHICLE'));

您现在还可以传递您要“合并”的任何一个字符串。

答案 3 :(得分:0)

您可以使用这种方法,该方法确实像您提到的那样利用Array.prototype.reduce

const getDirections = str => {
  //Split the string into an array and remove the whitespace
  const data = str.split('-').map(el => el.replace(/\s/g, ''));

  //Add to the accumulator if the prior element is different
  return data.reduce((accum, el, idx, arr) => {
    if (el !== accum[accum.length - 1]) {
      accum.push(el);
    }
    return accum;
  }, []);
}


const directions = getDirections("WALK - WALK - WALK - VEHICLE - WALK - WALK - VEHICLE - WALK - VEHICLE");

console.log(directions);

答案 4 :(得分:0)

const oldTrip = [
    { mode: 'WALK' },
    { mode: 'WALK' },
    { mode: 'VEHICLE' },
    { mode: 'VEHICLE' },
    { mode: 'WALK' }
];

const newTrip = oldTrip.reduce((acc, cur) => {
    if (cur.mode === 'WALK' && acc.length && acc[acc.length - 1].mode === 'WALK') {
        return acc;
    }
    acc.push(cur);
    return acc;
}, []);

console.log(newTrip);