Skip to content

Commit

Permalink
add zipWith and pairwiseWith
Browse files Browse the repository at this point in the history
  • Loading branch information
mo-ba committed Dec 13, 2023
1 parent a299bae commit b33cf93
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 3 deletions.
49 changes: 49 additions & 0 deletions docs/src/pages/en/array/operator/pairwiseWith.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: pairwiseWith
description: pairwiseWith
layout: ../../../../layouts/MainLayout.astro
---
Creates elements by combining adjacent elements in an array.

## Parameters

`fn` (Reduction): A reduction function that takes two elements of the array and returns a single value.

`array` (Array): An array of elements for which pairs of adjacent elements are to be created.

## Returns

A new array containing the result of applying the reduction function to pairs of adjacent elements.

## Example

```ts
import { pairwiseWith } from './pairwiseWith';

const inputArray = [1, 2, 3, 4, 5];
const sumReducer = (a, b) => a + b;

const resultArray = pairwiseWith(sumReducer)(inputArray);
// resultArray will be [3, 5, 7, 9]
```

## Notes

- The `pairwiseWith` function applies the provided reduction function to pairs of adjacent elements in the input array.

- The input array remains unaltered, and a new array is returned.

- If the input array has less than two elements, an empty array is returned since there are no adjacent elements to pair.

- The reduction function should take two arguments and return a value.

- This function does not modify the original array.



## See Also

- [map](./map)
- [reduce](./reduce)
- [pairwise](./pairwise)
- [zipWith](./zipWith)
41 changes: 41 additions & 0 deletions docs/src/pages/en/array/operator/zipWith.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
title: zipWith
description: zipWith
layout: ../../../../layouts/MainLayout.astro
---
Combines two arrays element-wise using a specified binary function.

## Signature

```ts
type zipWith = <E, F, R>(mapper: BinaryFunction<E, F, R>) => (arr1: E[]) => (arr2: F[]) => Array<R>
```
## Parameters
`mapper` (BinaryFunction): A binary function that takes elements from both arrays and returns a value.
`arr1` (Array): The first array to be zipped.
`arr2` (Array): The second array to be zipped.
## Returns
A new array containing the result of applying the `mapper` function to pairs of elements from `arr1` and `arr2`.
```ts
import { zipWith } from './zipWith';

const array1 = [1, 2, 3];
const array2 = ['a', 'b', 'c'];
const combineElements = (a, b) => `${a}-${b}`;

const resultArray = zipWith(combineElements)(array1)(array2);
// resultArray will be ['1-a', '2-b', '3-c']
```

## See Also
- [map](./map)
- [reduce](./reduce)
- [zip](./zip)
- [pairwiseWith](./pairwiseWith)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fnxt",
"version": "1.18.0",
"version": "1.19.0",
"description": "Functional Extensions for modern JavaScript",
"main": "./dist/cjs/index.js",
"module": "./dist/esm5/index.js",
Expand Down
4 changes: 2 additions & 2 deletions spec/core/array.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('array', () => {
'init', 'insertAt', 'interleave', 'isEmpty',
'iter', 'last', 'length',
'map', 'maxBy', 'minBy',
'pairwise', 'partition', 'push',
'pairwise','pairwiseWith', 'partition', 'push',
'reduce', 'reduceBack', 'replicate',
'rev', 'rotate', 'rotateBack',
'scan', 'scanBack', 'skip',
Expand All @@ -39,7 +39,7 @@ describe('array', () => {
'tryFindIndex', 'tryFindIndexBack', 'tryHead',
'tryLast', 'uniqueBy', 'updateAt',
'where', 'windowed', 'zip',
'zip3'
'zip3', 'zipWith'
]
.sort();
operators.map(name => './array/operator/' + name + '.spec')
Expand Down
18 changes: 18 additions & 0 deletions spec/core/array/operator/pairwiseWith.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {expect} from 'chai';
import {pairwiseWith} from '../../../../src/array';
import {checkThrow} from '../../../support/checkThrow';

describe('pairwiseWith', () => {
it('should pairwiseWith', () => {
const pairwiseSum = pairwiseWith<number>((a:number, b:number) => a + b);
expect(pairwiseSum([1, 2, 3, 4])).to.eql([3, 5, 7]);
expect(pairwiseSum([1,2])).to.eql([3]);
expect(pairwiseSum([1])).to.eql([]);
expect(pairwiseSum([])).to.eql([]);
});


it('should throw if null or undefined', () => {
checkThrow(pairwiseWith<number>((a, b) => a + b));
});
});
27 changes: 27 additions & 0 deletions spec/core/array/operator/zipWith.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {expect} from 'chai';
import {checkThrow} from '../../../support/checkThrow';
import {zipWith} from '../../../../src/array';

describe('zipWith', () => {


it('should zipWith', () => {
const fn = zipWith((a: number, b: number) => a + b)([1, 2, 3]);
expect(fn([4, 5, 6])).to.eql([5, 7, 9],);
});

it('should zipWith empty', () => {
const fn = zipWith((a: number, b: number) => a + b)([]);
expect(fn([])).to.eql([]);
});
it('should not zipWith if not same size', () => {
const fn = zipWith((a: number, b: number) => a + b)([1, 2]);
expect(() => fn([2])).to.throw();
});


it('should throw if null or undefined', () => {
const fn = zipWith((a: number, b: number) => a + b)([1]);
checkThrow(fn);
});
});
2 changes: 2 additions & 0 deletions src/array/operator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export * from './map';
export * from './maxBy';
export * from './minBy';
export * from './pairwise';
export * from './pairwiseWith';
export * from './partition';
export * from './push';
export * from './reduce';
Expand Down Expand Up @@ -83,3 +84,4 @@ export * from './where';
export * from './windowed';
export * from './zip';
export * from './zip3';
export * from './zipWith';
9 changes: 9 additions & 0 deletions src/array/operator/pairwiseWith.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {Reduction} from 'fnxt/fnxt-types';

export const pairwiseWith = <E>(fn: Reduction<E>) => (array: E[]): E[] => {
const result: E[] = [];
for (let i = 1; i < array.length; i++) {
result.push(fn(array[i - 1], array[i]));
}
return result;
};
12 changes: 12 additions & 0 deletions src/array/operator/zipWith.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {BinaryFunction} from 'fnxt/fnxt-types';

export const zipWith = <E, F, R>(mapper: BinaryFunction<E, F, R>) => (arr1: E[]) => (arr2: F[]): Array<R> => {
if (arr1.length !== arr2.length) {
throw new Error('Input arrays must have equal lengths');
}
const result: Array<R> = [];
for (let i = 0; i < arr1.length; i++) {
result.push(mapper(arr1[i], arr2[i]));
}
return result;
};

0 comments on commit b33cf93

Please sign in to comment.