Streaming library RXJS provides functionality for accumulating values using a buffer and then reducing them with a

I am working with a continuous stream of values

[ 0.5, 0.3, 0.4, 0.6, 1.4, 0.3, 0.6 ]

My goal is to transform this into

[           1         2         1 ]

The approach involves accumulating the values from the initial stream until a whole number is reached (at least 1) and then outputting that entire number while continuing to accumulate the remainder.

This concept seems challenging but I believe a solution might be found using switchMap.

Answer №1

My strategy is outlined below:

src$ = src$.pipe(publish());

const wholeNumber$ = src$.pipe(
  scan(
    (acc, crt) => (acc | 0) > 1 ? crt + (+(acc - (acc | 0)).toPrecision(1)) : acc + crt, 0
  ),
  map(v => (v | 0)),
  filter(v => v >= 1),
);

src$.pipe(
  buffer(wholeNumber$)
).subscribe();

publish ensures that the source isn't subscribed to multiple times. It's essentially a condensed version of multicast(new Subject()), which allows for multicasting a source. For this setup to function as intended, src$ needs to emit asynchronously so that the appropriate subscribers (wholeNumber$ and others) are registered by the Subject.

In situations where the source doesn't emit asynchronously, you can make it do so by utilizing

src$.pipe(observeOn(asapScheduler))
, which schedules each notification as a promise.

Let's dissect the callback passed to scan:

(acc, crt) => (acc | 0) > 1 ? crt + (+(acc - (acc | 0)).toPrecision(1)) : acc + crt`

The expression number | 0 is equivalent to Math.trunc(number).

Exploring

+(acc - (acc | 0)).toPrecision(1)
:

  • For instance, performing 1.2 - 1 yields: 0.199...96; with toPrecision(1): (1.2 - 1).toPrecision(1) = "0.2". Applying + turns 0.2 into a number.

Answer №2

Hey Andrei,

Your code was really helpful, I modified it to create a custom operator.


const customBuffer = (
  amount: number
): MonoTypeOperatorFunction<number> => (
  source: Observable<number>
): Observable<number> =>
  new Observable<number>((observer) => {
    let bufferSum = 0;
    return source.subscribe({
      next(value) {
        bufferSum += value;
        if (bufferSum < amount) return;
        const nextSum = Math.trunc(bufferSum);
        bufferSum -= nextSum;
        observer.next(nextSum);
      },
      error(error) {
        observer.error(error);
      },
      complete() {
        observer.complete();
      },
    });
  });

ticker.pipe(customBuffer(1)).subscribe();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Resolving search box setup problem in PrimeNG dataView

I am working on integrating p-dataView with Angular 5 but encountering an error Cannot read property 'split' of undefined at DataView.filter Despite checking the documentation, I have been unable to find a solution to this issue. It seems lik ...

Guide to capturing emitted values from eventemitter directly in the template

Currently, I am exploring the process of creating binding between a parent and child component using @Input, @Output, and EventEmitter decorators. Below is an example code snippet demonstrating this: @Output() newItemValue = new EventEmitter<string>( ...

Which property within the <mat-option> element is used for toggling checkboxes on and off?

I'm experimenting with dynamically checking/unchecking a checkbox in mat-option. What attribute can I use for this? I've successfully done the same thing with mat-checkbox using [(ngModel)]. Here's the snippet of my code: app.component.html ...

Issue with reading the current length of an array object in a while loop in Angular 6

After successfully splitting an array into parts, I decided to add some filters to only include the items in the list that have an action status of (4). However, I encountered a problem where the while loop couldn't read the length of the array. This ...

Secure your Angular 7 application with Spring Security and enable LDAP authentication for added protection

Having a significant issue, I've been stuck for days trying to figure out how to make my login app functional. I need it to send the username and password to Spring Boot for validation. Although I have the basic setup in place using Spring Boot's ...

Try switching out the set timeout function within typescript for Wavesurfer.js

I recently wrote a function that changes the source for an audio file using wavesurfer.js and then plays the song with the newly loaded audio file. While my code is currently functioning as intended, I can't help but feel there might be a more efficie ...

Error: The TypeScript aliases defined in tsconfig.json cannot be located

Having trouble finding the user-defined paths in tsconfig.json – TypeScript keeps throwing errors... Tried resetting the entire project, using default ts configs, double-checked all settings, and made sure everything was up-to-date. But still no luck. H ...

What is the proper way to incorporate the "pdf" package into a TypeScript project?

I recently installed pdf and its types using the following command: npm install --save pdf @types/pdf However, I am struggling to find any documentation on how to actually use this package. When I try the following code: import {PDFJS} from 'pdf&ap ...

Tips for displaying three divs in one row and three divs in another row

I'm aiming for a design with 3 divs in one row and another 3 in the next, like this But what I currently have is different. Can someone assist me in achieving the desired layout? MY HTML : <div class="category-food"> < ...

The argument provided, 'Item', cannot be assigned to the parameter, 'string'. TS2345 error encountered

Encountering an issue with type 'string'. Error code TS2345 Problem: Argument of type 'Item' is not compatible with parameter of type 'string'. TS2345 filter(resortList:ResortResult[], selectedFilters:SelectedFilters) { ...

Using keyvalue pipe in Angular to iterate over objects through inserted loops

My Customized Answer import { Question } from './question'; export class Answer { AnswerId: number; Content: string; IsCorrect: boolean; Mark: number; QuestionId: number; Question: Question; } My Personal TestStartComp ...

Declarations for TypeScript in NPM packages

In order to streamline my development process with bun.sh using workspaces as npm packages, I have created a tool available here. However, I am facing two issues: After bun installing the 'core' packages from npm and testing a sample, I encounte ...

Updating the value of a dropdown in React Testing Library

When testing an input, the process is as follows: it('test input', () => { const { getByTestId, getByLabelText } = render(<MyComponent />); const myButton = getByTestId('submit-button'); expect(myButton).toBeInTh ...

Is There a Comparable Feature to *ngIf in DevExtreme?

Currently, I am diving into the world of webapp development using DevExtreme. As a novice in coding, this is my first time exploring the functionalities of DevExtreme. Essentially, I am seeking guidance on how to display certain elements based on specific ...

When dealing with ng effects, an undefined value replaces the stream observable

Currently, I am working on a flow that involves adding a new object to another object's collection. This process starts with some domain-related tasks. Initially, I send an object to the backend and upon receiving a callback, I trigger another action ...

Transforming a "type containing promises as property values" in Typescript into a "type containing resolved promise values as properties"

Can this be achieved in Typescript? I am looking to transform something like the following: interface IPromiseObject { promiseA: Promise<number>; promiseB: Promise<string>; } Into this: interface IResolvedPromiseObject { promiseA: ...

Oops! The formGroup function in Angular 5 requires an instance of a FormGroup

While working with Angular 5, I encountered an error in this basic form. Here is the issue: Error Message: EditVisitanteDialogComponent.html:10 ERROR Error: formGroup expects a FormGroup instance. Please pass one in. Example: > > &l ...

What is a secure method for detecting variances between two objects in TypeScript?

I have two objects with similar properties. I want to compare the values of each property in both objects and find the differences. The following code is functional but generates TypeScript errors: export type Item = { name?: string; age?: number; l ...

Is there a faster way to create a typescript constructor that uses named parameters?

import { Model } from "../../../lib/db/Model"; export enum EUserRole { admin, teacher, user, } export class UserModel extends Model { name: string; phoneNo: number; role: EUserRole; createdAt: Date; constructor({ name, p ...

What is the best way to halt the parcel/babel/typescript process when encountering compilation errors or warnings?

index.jsx import React from 'react' import ReactDOM from 'react-dom' import Home from "./home"; const x:number = "aaa" const x:number = "aaa" const x:number = "aaa" ReactDOM.render(<Home/>, document.getElementById('root&ap ...