我想根据条件将数据的顺序对象合并到数组中。我有一个路线数组,其中每个对象都是该行程的一部分。考虑以下示例:
旅行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;
});
非常感谢您的帮助或朝着正确的方向前进!
答案 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);