pairwise - Verwerk twee opeenvolgende waarden als een paar
De pairwise operator koppelt twee opeenvolgende waarden die van een stream worden uitgegeven als een array [vorige waarde, huidige waarde] en voert ze samen uit. Dit is nuttig voor het vergelijken van de vorige waarde met de huidige waarde of voor het berekenen van de hoeveelheid verandering.
🔰 Basissyntax en gebruik
import { interval } from 'rxjs';
import { pairwise, take } from 'rxjs';
interval(1000).pipe(
take(6),
pairwise()
).subscribe(console.log);
// Output:
// [0, 1]
// [1, 2]
// [2, 3]
// [3, 4]
// [4, 5]- De eerste waarde (0) wordt niet alleen uitgevoerd, maar wordt uitgevoerd als
[0, 1]wanneer de tweede waarde (1) aankomt. - Altijd een paar van vorige waarde en huidige waarde wordt uitgevoerd.
🌐 RxJS Officiële Documentatie - pairwise
💡 Typische gebruikspatronen
- Berekening van de hoeveelheid muis- of touchbeweging
- Berekening van de hoeveelheid verandering (verschil) in prijzen of waarden
- Statusveranderingsdetectie (vergelijking van vorige status en huidige status)
- Bepaling van scrollrichting
🧠 Praktisch codevoorbeeld (met UI)
Dit voorbeeld toont de richting en hoeveelheid muisbeweging.
import { fromEvent } from 'rxjs';
import { map, pairwise } from 'rxjs';
// Maak uitvoergebied
const output = document.createElement('div');
output.style.marginTop = '10px';
output.style.fontFamily = 'monospace';
document.body.appendChild(output);
// Muisbewegingsgebeurtenis
fromEvent<MouseEvent>(document, 'mousemove').pipe(
map(event => ({ x: event.clientX, y: event.clientY })),
pairwise()
).subscribe(([prev, curr]) => {
const deltaX = curr.x - prev.x;
const deltaY = curr.y - prev.y;
const direction = deltaX > 0 ? 'Rechts' : deltaX < 0 ? 'Links' : 'Gestopt';
output.innerHTML = `
Vorige: (${prev.x}, ${prev.y})<br>
Huidige: (${curr.x}, ${curr.y})<br>
Beweging: Δx=${deltaX}, Δy=${deltaY}<br>
Richting: ${direction}
`;
});- Wanneer de muis wordt bewogen, worden de vorige en huidige coördinaten en de hoeveelheid beweging weergegeven.
- Met
pairwisekunnen de vorige en huidige coördinaten automatisch in paren worden verkregen.
🎯 Voorbeeld van het berekenen van de hoeveelheid verandering in een getal
Hier is een praktisch voorbeeld van het berekenen van de hoeveelheid verandering (verschil) in een numerieke waardestroom.
import { interval } from 'rxjs';
import { map, pairwise, take } from 'rxjs';
// 0, 1, 4, 9, 16, 25 (kwadraat getallen)
interval(500).pipe(
take(6),
map(n => n * n),
pairwise(),
map(([prev, curr]) => ({
prev,
curr,
diff: curr - prev
}))
).subscribe(result => {
console.log(`${result.prev} → ${result.curr} (verschil: +${result.diff})`);
});
// Output:
// 0 → 1 (verschil: +1)
// 1 → 4 (verschil: +3)
// 4 → 9 (verschil: +5)
// 9 → 16 (verschil: +7)
// 16 → 25 (verschil: +9)🎯 Bepaling van scrollrichting
Hieronder volgt een voorbeeld van het bepalen van de scrollrichting (omhoog/omlaag).
import { fromEvent } from 'rxjs';
import { map, pairwise, throttleTime } from 'rxjs';
// Maak vast weergave uitvoergebied
const output = document.createElement('div');
output.style.position = 'fixed';
output.style.top = '10px';
output.style.right = '10px';
output.style.padding = '15px';
output.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
output.style.color = 'white';
output.style.fontFamily = 'monospace';
output.style.fontSize = '14px';
output.style.borderRadius = '5px';
output.style.zIndex = '9999';
document.body.appendChild(output);
// Dummy-inhoud voor scrollen
const content = document.createElement('div');
content.style.height = '200vh'; // Dubbele paginahoogte
content.innerHTML = '<h1>Scroll alstublieft naar beneden</h1>';
document.body.appendChild(content);
// Krijg scrollpositie
fromEvent(window, 'scroll').pipe(
throttleTime(100), // Throttle elke 100ms
map(() => window.scrollY),
pairwise()
).subscribe(([prevY, currY]) => {
const diff = currY - prevY;
const direction = diff > 0 ? '↓ Omlaag' : '↑ Omhoog';
const arrow = diff > 0 ? '⬇️' : '⬆️';
output.innerHTML = `
${arrow} Scrollrichting: ${direction}<br>
Vorige positie: ${prevY.toFixed(0)}px<br>
Huidige positie: ${currY.toFixed(0)}px<br>
Beweging: ${Math.abs(diff).toFixed(0)}px
`;
});- Als de pagina wordt gescrolld, worden de richting en positie-informatie weergegeven in een vast gebied rechtsboven.
pairwisestelt u in staat om automatisch de vorige en huidige scrollpositie in paren te krijgen.
🎯 Type-veilig pairwise gebruiken
Dit is een voorbeeld van het benutten van TypeScript's type-inferentie.
import { from } from 'rxjs';
import { pairwise } from 'rxjs';
interface Stock {
symbol: string;
price: number;
timestamp: number;
}
const stockPrices: Stock[] = [
{ symbol: 'AAPL', price: 150, timestamp: 1000 },
{ symbol: 'AAPL', price: 152, timestamp: 2000 },
{ symbol: 'AAPL', price: 148, timestamp: 3000 },
{ symbol: 'AAPL', price: 155, timestamp: 4000 },
];
from(stockPrices).pipe(
pairwise()
).subscribe(([prev, curr]) => {
const change = curr.price - prev.price;
const changePercent = ((change / prev.price) * 100).toFixed(2);
const trend = change > 0 ? '📈' : change < 0 ? '📉' : '➡️';
console.log(
`${curr.symbol}: $${prev.price} → $${curr.price} ` +
`(${changePercent}%) ${trend}`
);
});
// Output:
// AAPL: $150 → $152 (1.33%) 📈
// AAPL: $152 → $148 (-2.63%) 📉
// AAPL: $148 → $155 (4.73%) 📈🔍 Vergelijking met bufferCount(2, 1)
pairwise() is equivalent aan bufferCount(2, 1).
import { of } from 'rxjs';
import { pairwise, bufferCount } from 'rxjs';
const source$ = of(1, 2, 3, 4, 5);
console.log('=== pairwise ===');
source$.pipe(pairwise()).subscribe(console.log);
// Output: [1,2], [2,3], [3,4], [4,5]
console.log('=== bufferCount(2, 1) ===');
source$.pipe(bufferCount(2, 1)).subscribe(console.log);
// Output: [1,2], [2,3], [3,4], [4,5]Gebruiksverschillen:
pairwise(): Behandelt expliciet paren van twee opeenvolgende waarden, en de intentie van de code is duidelijkbufferCount(2, 1): Flexibeler (kan meer dan 3 venstergroottes aan)
⚠️ Opmerkingen
De eerste waarde wordt niet uitgevoerd
Aangezien pairwise niets uitvoert tot de twee waarden uitgelijnd zijn, kan de eerste waarde niet alleen worden verkregen.
import { of } from 'rxjs';
import { pairwise } from 'rxjs';
of(1).pipe(pairwise()).subscribe({
next: console.log,
complete: () => console.log('Voltooid')
});
// Output:
// Voltooid
// (Geen waarden worden uitgevoerd)Tegenmaatregel: Als u ook de eerste waarde wilt verwerken, voeg een initiële waarde toe met startWith.
import { of } from 'rxjs';
import { startWith, pairwise } from 'rxjs';
of(10, 20, 30).pipe(
startWith(0),
pairwise()
).subscribe(console.log);
// Output:
// [0, 10]
// [10, 20]
// [20, 30]Geheugengebruik
Aangezien pairwise altijd slechts één vorige waarde bewaart, is het geheugenefficiënt.
📚 Gerelateerde operators
scan- Complexer accumulatieprocesbufferCount- Vat waarden samen voor elk gespecificeerd aantal itemsdistinctUntilChanged- Verwijder opeenvolgende dubbele waardenstartWith- Voeg initiële waarde toe
Samenvatting
De pairwise operator voert twee opeenvolgende waarden uit als [vorige waarde, huidige waarde] paren. Dit is zeer nuttig voor situaties waar een vergelijking van de vorige waarde en de huidige waarde nodig is, zoals het volgen van muisbewegingen, het berekenen van prijsveranderingen en het detecteren van statusovergangen. Merk op dat de eerste waarde niet wordt uitgevoerd tot de tweede waarde aankomt, maar dit kan worden afgehandeld door een initiële waarde toe te voegen met startWith.