diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/README.md b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/README.md new file mode 100644 index 00000000000..0b0507c2f39 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/README.md @@ -0,0 +1,146 @@ + + +# forEachGraphemeCluster + +> Invokes a function for each grapheme cluster (i.e., user-perceived character) in a string. + + + +
+ +
+ + + + + +
+ +## Usage + +```javascript +var forEachGraphemeCluster = require( '@stdlib/string/base/for-each-grapheme-cluster' ); +``` + +#### forEachGraphemeCluster( str, clbk\[, thisArg ] ) + +Invokes a function for each grapheme cluster (i.e., user-perceived character) in a string. + +```javascript +function log( value, index ) { + console.log( '%d: %s', index, value ); +} + +forEachGraphemeCluster( 'Beep!', log ); +/* => + 0: B + 1: e + 2: e + 3: p + 4: ! +*/ +``` + +The invoked function is provided three arguments: + +- **value**: grapheme cluster. +- **index**: starting grapheme cluster index. +- **str**: input string. + +To set the function execution context, provide a `thisArg`. + +```javascript +function clbk() { + this.count += 1; +} + +var str = 'Hello, world!'; + +var ctx = { + 'count': 0 +}; + +forEachGraphemeCluster( str, clbk, ctx ); + +var bool = ( str.length === ctx.count ); +// returns true +``` + +
+ + + + + +
+ +
+ + + + + +
+ +## Examples + + + +```javascript +var forEachGraphemeCluster = require( '@stdlib/string/base/for-each-grapheme-cluster' ); + +function log( value, index ) { + console.log( '%d: %s', index, value ); +} + +forEachGraphemeCluster( 'presidential election', log ); +forEachGraphemeCluster( 'Iñtërnâtiônàlizætiøn', log ); +forEachGraphemeCluster( '🌷🍕', log ); +forEachGraphemeCluster( '\uD834\uDD1E', log ); +``` + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/benchmark/benchmark.js b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/benchmark/benchmark.js new file mode 100644 index 00000000000..f802ee4cd85 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/benchmark/benchmark.js @@ -0,0 +1,61 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var forEach = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var out; + var i; + + values = [ + 'Iñtërnâtiônàlizætiøn', + 'presidential election', + '🐶🐮🐷🐰🐸' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = forEach( values[ i%values.length ], clbk ); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( !isString( out ) ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function clbk( v ) { + if ( typeof v !== 'string' ) { + b.fail( 'unexpected value' ); + } + } +}); diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/docs/repl.txt b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/docs/repl.txt new file mode 100644 index 00000000000..a479c2b8f61 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/docs/repl.txt @@ -0,0 +1,38 @@ + +{{alias}}( str, clbk[, thisArg] ) + Invokes a function for each grapheme cluster (i.e., user-perceived + character) in a string. + + When invoked, the provided function is provided three arguments: + + - value: grapheme cluster + - index: starting grapheme cluster index + - str: input string + + Parameters + ---------- + str: string + Input string over which to iterate. + + clbk: Function + The function to invoke for each grapheme cluster in the input string. + + thisArg: any (optional) + Execution context. + + Returns + ------- + out: string + Input string. + + Examples + -------- + > var n = 0; + > function fcn() { n += 1; }; + > {{alias}}( 'hello world!', fcn ); + > n + 12 + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/docs/types/index.d.ts b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/docs/types/index.d.ts new file mode 100644 index 00000000000..e68abee3684 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/docs/types/index.d.ts @@ -0,0 +1,93 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// TypeScript Version: 2.0 + +/** +* Callback invoked for each grapheme cluster (i.e., user-perceived character) in a string. +* +* @returns result +*/ +type Nullary = () => any; + +/** +* Callback invoked for each grapheme cluster (i.e., user-perceived character) in a string. +* +* @param value - grapheme cluster +* @returns result +*/ +type Unary = ( value: string ) => any; + +/** +* Callback invoked for each grapheme cluster (i.e., user-perceived character) in a string. +* +* @param value - grapheme cluster +* @param index - string grapheme cluster index +* @returns result +*/ +type Binary = ( value: string, index: number ) => any; + +/** +* Callback invoked for each grapheme cluster (i.e., user-perceived character) in a string. +* +* @param value - grapheme cluster +* @param index - string grapheme cluster index +* @param str - input string +* @returns result +*/ +type Ternary = ( value: string, index: number, str: string ) => any; + +/** +* Callback invoked for each grapheme cluster (i.e., user-perceived character) in a string. +* +* @param value - grapheme cluster +* @param index - starting grapheme cluster index +* @param str - input string +* @returns result +*/ +type Callback = Nullary | Unary | Binary | Ternary; + +/** +* Invokes a function for each grapheme cluster (i.e., user-perceived character) in a string. +* +* ## Notes +* +* - When invoked, the provided function is provided three arguments: +* +* - **value**: grapheme cluster. +* - **index**: starting grapheme cluster index. +* - **str**: input string. +* +* @param str - input string +* @param clbk - function to invoke +* @param thisArg - execution context +* @returns input string +* +* @example +* function log( value, index ) { +* console.log( '%d: %s', index, value ); +* } +* +* forEach( 'Hello, World!', log ); +*/ +declare function forEach( str: string, clbk: Callback, thisArg?: any ): string; + + +// EXPORTS // + +export = forEach; diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/docs/types/test.ts b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/docs/types/test.ts new file mode 100644 index 00000000000..c1d98d1414d --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/docs/types/test.ts @@ -0,0 +1,85 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import forEach = require( './index' ); + +/** +* Callback function. +* +* @param v - argument +* @returns result +*/ +function clbk( v: string ): string { + return v; +} + +// TESTS // + +// The function returns a string... +{ + forEach( 'presidential election', clbk ); // $ExpectType string + forEach( 'Iñtërnâtiônàlizætiøn', clbk, {} ); // $ExpectType string +} + +// The compiler throws an error if the function is provided a first argument which is not a string... +{ + forEach( 1, clbk ); // $ExpectError + forEach( false, clbk ); // $ExpectError + forEach( true, clbk ); // $ExpectError + forEach( null, clbk ); // $ExpectError + forEach( [], clbk ); // $ExpectError + forEach( {}, clbk ); // $ExpectError + forEach( ( x: number ): number => x, clbk ); // $ExpectError + + forEach( 1, clbk, {} ); // $ExpectError + forEach( false, clbk, {} ); // $ExpectError + forEach( true, clbk, {} ); // $ExpectError + forEach( null, clbk, {} ); // $ExpectError + forEach( [], clbk, {} ); // $ExpectError + forEach( {}, clbk, {} ); // $ExpectError + forEach( ( x: number ): number => x, clbk, {} ); // $ExpectError +} + +// The compiler throws an error if the function is provided a second argument which is not a function having a supported signature... +{ + forEach( 'presidential election', 'abc' ); // $ExpectError + forEach( 'presidential election', 2 ); // $ExpectError + forEach( 'presidential election', true ); // $ExpectError + forEach( 'presidential election', false ); // $ExpectError + forEach( 'presidential election', null ); // $ExpectError + forEach( 'presidential election', {} ); // $ExpectError + forEach( 'presidential election', [] ); // $ExpectError + + forEach( 'presidential election', 'abc', {} ); // $ExpectError + forEach( 'presidential election', 2, {} ); // $ExpectError + forEach( 'presidential election', true, {} ); // $ExpectError + forEach( 'presidential election', false, {} ); // $ExpectError + forEach( 'presidential election', null, {} ); // $ExpectError + forEach( 'presidential election', {}, {} ); // $ExpectError + forEach( 'presidential election', [], {} ); // $ExpectError + + forEach( 'presidential election', ( x: number ): number => x ); // $ExpectError + forEach( 'presidential election', ( x: number ): number => x, {} ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + forEach(); // $ExpectError + forEach( 'presidential election' ); // $ExpectError + forEach( 'presidential election', clbk, {}, 3 ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/examples/index.js b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/examples/index.js new file mode 100644 index 00000000000..b93ac6cd1ce --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/examples/index.js @@ -0,0 +1,30 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var forEachGraphemeCluster = require( './../lib' ); + +function log( value, index ) { + console.log( '%d: %s', index, value ); +} + +forEachGraphemeCluster( 'presidential election', log ); +forEachGraphemeCluster( 'Iñtërnâtiônàlizætiøn', log ); +forEachGraphemeCluster( '🌷🍕', log ); +forEachGraphemeCluster( '\uD834\uDD1E', log ); diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/lib/index.js b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/lib/index.js new file mode 100644 index 00000000000..96155d9db01 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/lib/index.js @@ -0,0 +1,43 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Invoke a function for each grapheme cluster (i.e., user-perceived character) in a string. +* +* @module @stdlib/string/base/for-each-grapheme-cluster +* +* @example +* var forEach = require( '@stdlib/string/base/for-each-grapheme-cluster' ); +* +* function log( value, index ) { +* console.log( '%d: %s', index, value ); +* } +* +* forEach( 'Hello', log ); +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/lib/main.js b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/lib/main.js new file mode 100644 index 00000000000..080eac2a5de --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/lib/main.js @@ -0,0 +1,64 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var nextGraphemeClusterBreak = require( '@stdlib/string/next-grapheme-cluster-break' ); + + +// MAIN // + +/** +* Invokes a function for each grapheme cluster (i.e., user-perceived character) in a string. +* +* @param {string} str - input string +* @param {Function} clbk - function to invoke +* @param {*} [thisArg] - execution context +* @returns {string} input string +* +* @example +* function log( value, index ) { +* console.log( '%d: %s', index, value ); +* } +* +* forEach( 'Hello', log ); +*/ +function forEach( str, clbk, thisArg ) { + var len; + var idx; + var brk; + + len = str.length; + idx = 0; + while ( idx < len ) { + brk = nextGraphemeClusterBreak( str, idx ); + if ( brk === -1 ) { + brk = len; + } + clbk.call( thisArg, str.substring( idx, brk ), idx, str ); + idx = brk; + } + return str; +} + + +// EXPORTS // + +module.exports = forEach; diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/package.json b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/package.json new file mode 100644 index 00000000000..60cb2ec1ffa --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/package.json @@ -0,0 +1,69 @@ +{ + "name": "@stdlib/string/base/for-each-grapheme-cluster", + "version": "0.0.0", + "description": "Invoke a function for each grapheme cluster (i.e., user-perceived character) in a string.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdutils", + "stdutil", + "utilities", + "utility", + "utils", + "util", + "for", + "each", + "foreach", + "iterate", + "stdstring", + "string", + "str", + "grapheme", + "unicode" + ] +} diff --git a/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/test/test.js b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/test/test.js new file mode 100644 index 00000000000..b5b543783e9 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/for-each-grapheme-cluster/test/test.js @@ -0,0 +1,164 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var noop = require( '@stdlib/utils/noop' ); +var forEach = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof forEach, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'if provided an empty string, the function never invokes a provided function', function test( t ) { + var out = forEach( '', fcn ); + t.strictEqual( out, '', 'returns expected value' ); + t.end(); + + function fcn() { + t.fail( 'should not be invoked' ); + } +}); + +tape( 'the function returns a provided string', function test( t ) { + var str; + var out; + + str = 'Hello, world'; + + out = forEach( str, noop ); + t.strictEqual( out, str, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function invokes a provided function for each grapheme cluster of a provided string', function test( t ) { + var expected; + var actual; + var str; + + str = 'Hello, world'; + expected = [ + 'H', + 'e', + 'l', + 'l', + 'o', + ',', + ' ', + 'w', + 'o', + 'r', + 'l', + 'd' + ]; + + actual = []; + forEach( str, copy ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); + + function copy( value ) { + actual.push( value ); + } +}); + +tape( 'the function invokes a provided function for each grapheme cluster of the string (Unicode)', function test( t ) { + var expected; + var actual; + var str; + + str = 'Hello, world \uD834\uDD1E'; + expected = [ + 'H', + 'e', + 'l', + 'l', + 'o', + ',', + ' ', + 'w', + 'o', + 'r', + 'l', + 'd', + ' ', + '\uD834\uDD1E' + ]; + + actual = []; + forEach( str, copy ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); + + function copy( value ) { + actual.push( value ); + } +}); + +tape( 'the function invokes a provided function for each grapheme cluster of the string (emoji)', function test( t ) { + var expected; + var actual; + var str; + + str = '🌷🍕👉🏿'; + expected = [ + '🌷', + '🍕', + '👉🏿' + ]; + + actual = []; + forEach( str, copy ); + + t.deepEqual( actual, expected, 'returns expected value' ); + t.end(); + + function copy( value ) { + actual.push( value ); + } +}); + +tape( 'the function supports providing an execution context', function test( t ) { + var ctx; + var str; + + str = 'Hello, world'; + ctx = { + 'count': 0 + }; + + forEach( str, count, ctx ); + + t.strictEqual( ctx.count, str.length, 'returns expected value' ); + t.end(); + + function count() { + this.count += 1; // eslint-disable-line no-invalid-this + } +});