Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export { default as findIndex } from "./src/findIndex";
export { default as findLast } from "./src/findLast";
export { default as findLastIndex } from "./src/findLastIndex";
export { default as map } from "./src/map";
export { default as mapParallel } from "./src/mapParallel";
export { default as reduce } from "./src/reduce";
export { default as reduceRight } from "./src/reduceRight";
export { default as some } from "./src/some";
4 changes: 1 addition & 3 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.some = exports.reduceRight = exports.reduce = exports.mapParallel = exports.map = exports.findLastIndex = exports.findLast = exports.findIndex = exports.find = exports.filter = exports.every = void 0;
exports.some = exports.reduceRight = exports.reduce = exports.map = exports.findLastIndex = exports.findLast = exports.findIndex = exports.find = exports.filter = exports.every = void 0;
var every_1 = require("./src/every");
Object.defineProperty(exports, "every", { enumerable: true, get: function () { return __importDefault(every_1).default; } });
var filter_1 = require("./src/filter");
Expand All @@ -18,8 +18,6 @@ var findLastIndex_1 = require("./src/findLastIndex");
Object.defineProperty(exports, "findLastIndex", { enumerable: true, get: function () { return __importDefault(findLastIndex_1).default; } });
var map_1 = require("./src/map");
Object.defineProperty(exports, "map", { enumerable: true, get: function () { return __importDefault(map_1).default; } });
var mapParallel_1 = require("./src/mapParallel");
Object.defineProperty(exports, "mapParallel", { enumerable: true, get: function () { return __importDefault(mapParallel_1).default; } });
var reduce_1 = require("./src/reduce");
Object.defineProperty(exports, "reduce", { enumerable: true, get: function () { return __importDefault(reduce_1).default; } });
var reduceRight_1 = require("./src/reduceRight");
Expand Down
7 changes: 6 additions & 1 deletion dist/src/map.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
/**
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map|MDN Documentation Array.prototype.map}
* Optionally, you can batch your iterations to more efficiently await blocking iteratee function calls using the batchIterations and batchSize attributes on the options parameter.
*
* @static
* @since 1.0.0
* @param {T[]} array
* @param {(value: T, index: number) => Promise<V>} iteratee
* @param {{ batchIterations: boolean; batchSize: number }} [options]
* @returns {Promise<V[]>}
* @example
* const array = [1, 2, 3];
* const doubledArray = await map(array, async (value) => value * 2);
*/
export default function map<T, V>(array: T[], iteratee: (value: T, index: number) => Promise<V>): Promise<V[]>;
export default function map<T, V>(array: T[], iteratee: (value: T, index: number) => Promise<V>, options?: {
batchIterations: boolean;
batchSize: number;
}): Promise<V[]>;
48 changes: 47 additions & 1 deletion dist/src/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,65 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.default = map;
/**
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map|MDN Documentation Array.prototype.map}
* Optionally, you can batch your iterations to more efficiently await blocking iteratee function calls using the batchIterations and batchSize attributes on the options parameter.
*
* @static
* @since 1.0.0
* @param {T[]} array
* @param {(value: T, index: number) => Promise<V>} iteratee
* @param {{ batchIterations: boolean; batchSize: number }} [options]
* @returns {Promise<V[]>}
* @example
* const array = [1, 2, 3];
* const doubledArray = await map(array, async (value) => value * 2);
*/
async function map(array, iteratee) {
async function map(array, iteratee, options) {
if (!Array.isArray(array) || !array?.length)
return [];
if (options?.batchIterations) {
return await mapParallel(array, iteratee, options.batchSize);
}
else {
return await mapSerial(array, iteratee);
}
}
async function mapParallel(array, iteratee, batchSize) {
const arrayWithIndexKeys = array.map((item, i) => {
return {
task: item,
index: i,
};
});
const effectiveMaxBatchSize = batchSize > array.length ? array.length : batchSize;
const results = [];
await Promise.all(Array(effectiveMaxBatchSize)
.fill(undefined)
.map(async () => {
const resultsWithIndex = await takeAndCompleteFromQueueUntilDone(arrayWithIndexKeys, iteratee);
resultsWithIndex.forEach((result) => {
results[result.index] = result.result;
});
}));
return results;
}
/**
* take and complete tasks from a queue until that queue is empty.
* @param {{ task: T; index: number }[]} array
* @param {(value: T, index: number) => Promise<V>} iteratee
*/
async function takeAndCompleteFromQueueUntilDone(array, iteratee) {
const item = array.shift();
if (!item) {
return [];
}
const completedTask = await iteratee(item.task, item.index);
const followingCompletedTasks = await takeAndCompleteFromQueueUntilDone(array, iteratee);
return followingCompletedTasks.concat({
result: completedTask,
index: item.index,
});
}
async function mapSerial(array, iteratee) {
const results = [];
for (let index = 0; index < array.length; index++) {
const element = array[index];
Expand Down
14 changes: 0 additions & 14 deletions dist/src/mapParallel.d.ts

This file was deleted.

54 changes: 0 additions & 54 deletions dist/src/mapParallel.js

This file was deleted.

1 change: 0 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export { default as findIndex } from "./src/findIndex";
export { default as findLast } from "./src/findLast";
export { default as findLastIndex } from "./src/findLastIndex";
export { default as map } from "./src/map";
export { default as mapParallel } from "./src/mapParallel";
export { default as reduce } from "./src/reduce";
export { default as reduceRight } from "./src/reduceRight";
export { default as some } from "./src/some";
76 changes: 75 additions & 1 deletion src/map.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,95 @@
/**
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map|MDN Documentation Array.prototype.map}
* Optionally, you can batch your iterations to more efficiently await blocking iteratee function calls using the batchIterations and batchSize attributes on the options parameter.
*
* @static
* @since 1.0.0
* @param {T[]} array
* @param {(value: T, index: number) => Promise<V>} iteratee
* @param {{ batchIterations: boolean; batchSize: number }} [options]
* @returns {Promise<V[]>}
* @example
* const array = [1, 2, 3];
* const doubledArray = await map(array, async (value) => value * 2);
*/
export default async function map<T, V>(
array: T[],
iteratee: (value: T, index: number) => Promise<V>
iteratee: (value: T, index: number) => Promise<V>,
options?: { batchIterations: boolean; batchSize: number }
): Promise<V[]> {
if (!Array.isArray(array) || !array?.length) return [];

if (options?.batchIterations) {
return await mapParallel(array, iteratee, options.batchSize);
} else {
return await mapSerial(array, iteratee);
}
}

async function mapParallel<T, V>(
array: T[],
iteratee: (value: T, index: number) => Promise<V>,
batchSize: number
): Promise<V[]> {
const arrayWithIndexKeys = array.map((item, i) => {
return {
task: item,
index: i,
};
});

const effectiveMaxBatchSize =
batchSize > array.length ? array.length : batchSize;

const results: V[] = [];
await Promise.all(
Array(effectiveMaxBatchSize)
.fill(undefined)
.map(async () => {
const resultsWithIndex = await takeAndCompleteFromQueueUntilDone(
arrayWithIndexKeys,
iteratee
);

resultsWithIndex.forEach((result) => {
results[result.index] = result.result;
});
})
);

return results;
}

/**
* take and complete tasks from a queue until that queue is empty.
* @param {{ task: T; index: number }[]} array
* @param {(value: T, index: number) => Promise<V>} iteratee
*/
async function takeAndCompleteFromQueueUntilDone<T, V>(
array: { task: T; index: number }[],
iteratee: (value: T, index: number) => Promise<V>
): Promise<{ result: V; index: number }[]> {
const item = array.shift();
if (!item) {
return [];
}

const completedTask = await iteratee(item.task, item.index);
const followingCompletedTasks = await takeAndCompleteFromQueueUntilDone<T, V>(
array,
iteratee
);

return followingCompletedTasks.concat({
result: completedTask,
index: item.index,
});
}

async function mapSerial<T, V>(
array: T[],
iteratee: (value: T, index: number) => Promise<V>
): Promise<V[]> {
const results: V[] = [];
for (let index = 0; index < array.length; index++) {
const element = array[index];
Expand Down
74 changes: 0 additions & 74 deletions src/mapParallel.ts

This file was deleted.

Loading