Important Notice: ArrayTs
library is in Beta mode being actively developed. Unit Testing for ArrayTs
is now underway. If a production quality code version must be used, please refer to the previous JavaScript
library version ArrayJs
. This notice will be removed, when all offered IEnumerable<T>
type methods gain code coverage, and implement proper error handling techniques.
ArrayTs
is a TypeScript
library
which enhances the JavaScript
array
type by exposing extension methods, similar to the IEnumerable<T>
interface in Microsoft's
.NET Core
framework. The generic Array<T>
interface is
being extended for the ArrayTs
implementation of the
IEnumerable<T>
interface features, exposed to the JavaScript
array
type.
Roadmap:
1. Universal Module Definition (UMD): Desire to refactor the
ts
namespace partially/fully out of theArrayTs
project codebase, in favor of adopting aUMD
modular based design approach. To ensure the final transpiled/compiledJavaScript
module definitions are accurate, adding additional build tools to thebuild workflow
is now necessary, e.g.Browserify
&tsify
. Using aUMD
, modular based design approach, forArrayTs
, provides a superior method, for avoiding naming collisions with all othernpm
packages, duplicate namespaces or user-defined codebases.2. Browserify / tsify: Desire to implement
Browserify
&tsify
. These build tools will greatly simplify importing content and downstream dependencies, through usingrequire()
in scripts, as well as provide a simple configuration API integrated into the build pipeline.3. Unit Testing - Positive: Desire to flush out & fix current bugs with
Happy Path
paradigm in mind, e.g.InnerJoin()
does not work.4. Error/Throw Logic Refactor: Desire to refactor logic lines that contain
throw new Error("...")
style logic implementations in favor of a response style continuation or observation much like that ofneverthrow
, as mentioned in theneverthrow dev.to
article.5. Unit Testing - Negative: Desire to flush out new bugs by trying to use failure cases.
6. Code Documentation Updates: Desire to finish documentation and code comments for every method, interface and readme.
7.
npm
Package: Desire to create thenpm
package array-ts to deploy package code tonpm
in an automated fashion.8. Create Documentation Site: Desire to create a Documentation Website to help others easily understand and implement
ArrayTs
.
Known Issues:
03/24/2020: Ryan Mauldin
discovered issue with InnerJoin() when running
index.html
.
See TypeScript
usage:
ArrayTs
library includes some functionality beyond the IEnumerable<T>
interface as well, such as the Clone()
method as shown below, which offers a Deep Cloning capability
to the JavaScript
array
.
TypeScript
code:
const numbers: Array<number> = [ 1, 2, 3, 4 ];
let clonedNumbers: ts.IArray<number> = new ts.IArray<number>();
if (!ts.IsNullOrEmpty(numbers)) clonedNumbers = (<ts.IArray<number>>numbers).Clone();
console.log("Cloned Numbers Greater Than 2:");
for (const number of clonedNumbers.Where(p => p > 2)) { console.log(number); }
TypeScript
output:
Cloned Numbers Greater Than 2:
3
4
See JavaScript
usage:
ArrayTs
library includes a set of functional use-case scenarios,
implemented in index.html
, which follow the
Happy Path
paradigm. See index.html
,
for the full working example.
JavaScript
code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head><script src="./ArrayTs.js"></script></head>
<body>
<script type="text/javascript">
function ready(fn) {
// ... see index.html for implementation ...
}
ready(function() {
var output = document.getElementById("output");
var log = new ts.IArray();
var source = new ts.IArray([
{ Id: 1, Name: "Item 1" },
{ Id: 2, Name: "Item 2" },
{ Id: 3, Name: "Item 3" },
{ Id: 4, Name: "Item 4" },
{ Id: 5, Name: "Item 5" },
{ Id: 6, Name: "Item 6" },
{ Id: 7, Name: "Item 7" }
]);
var petOwners = new ts.IArray([
{ Name: "Higa, Sidney", Pets: ["Scruffy", "Sam"] },
{ Name: "Ashkenazi, Ronen", Pets: ["Walker", "Sugar"] },
{ Name: "Price, Vernette", Pets: ["Scratches", "Diesel"] }
]);
// Where & OrderByDesc
var query = source
.Where("m=>m.Id > 3 && m.Id < 6")
.OrderByDescending("m=>m.Name");
log.push("<b>Where & OrderByDesc</b>", "<br />");
query.forEach(function(o) {
log.push("Id = " + o.Id + ", Name = " + o.Name);
log.push("<br />");
});
//Skip & Take
query = source.Skip(3).Take(2);
log.push("<br />");
log.push("<b>Skip & Take</b>");
log.push("<br />");
query.forEach(function(o) {
log.push("Id = " + o.Id + ", Name = " + o.Name);
log.push("<br />");
});
//Select
query = petOwners.Select("m=>m.Pets");
log.push("<br />");
log.push("<b>Select</b>");
log.push("<br />");
query.forEach(function(o) {
log.push(o.join());
log.push("<br />");
});
if (!query.Any()) log.push("<br />");
//Zip
var numbers = new ts.IArray([1, 2, 3, 4]);
var words = new ts.IArray(["one", "two", "three"]);
var numbersAndWords = numbers.Zip(
words,
'(first, second) => first + " " + second'
);
log.push("<br />");
log.push("<b>Zip</b>");
log.push("<br />");
numbersAndWords.forEach(function(o) {
log.push(o);
log.push("<br />");
});
output.innerHTML = unescape(log.join(""));
});
</script>
<h1>ArrayTs Demo Page</h1>
<div><br /></div>
<div id="output"></div>
<div><br /></div>
</body>
</html>
JavaScript
output:
ArrayTs Demo Page
Where & OrderByDesc
Id = 5, Name = Item 5
Id = 4, Name = Item 4
Skip & Take
Id = 4, Name = Item 4
Id = 5, Name = Item 5
Select
Scruffy,Sam Walker,Sugar Scratches,Diesel
Zip
1 one
2 two
3 three
Version Specifics:
Current Version: ArrayTs (2020)
, Author: Ryan Mauldin
Refactor Notes:
02/27/2020: Ryan Mauldin
, refactored the original ArrayJs (2013)
library using a completely TypeScript
& non prototype-based approach.
History:
Original Version: ArrayJs (2013)
, Authors: Jack Godwin
&
Ryan Mauldin
ArrayTs (2020)
gained its origins from an earlier
JavaScript
based project ArrayJs (2013)
.
ArrayJs
, differed in implementation semantics, in that the
IEnumerable<T>
extension methods exposed to the JavaScript
array
type, were previously coupled directly to the the JavaScript
array
type, through prototype extension method definitions,
e.g., Array.prototype.zip = function (second, zipFn) {...}
.
When prototype extension method definitions are used in isolation of other conflicting
libraries, the extended prototype coding conventions are practical and work as intended.
Prototype extension method definitions are available to be called directly from the
code context of the extended root type, e.g. JavaScript
array
type. Prototype-based extension method
approaches will typically not incur additional code implementation overhead costs, in regards to
downstream code implementation complexity.
Utilizing prototype-based, extension method conventions, was not a favorable design approach,
when contemplating the redesign with ArrayTs
.
The stance ArrayTs
is taking now, is that this library
must be reliable and resilient to failure, throughout an application's entire development
life-cycle. ArrayTs
must remain resilient to failure when
adding or swapping out, additional external JavaScript
or
TypeScript
repository packages from popular sources, e.g.
npm
or bower
. ArrayTs
will remain side-effect free, while developers are implementing solution configuration changes, as well as when
upgrading TypeScript
versions. ArrayTs
now has the capability to gain adoption by the development community, as code integration
is safeguarded by the UMD
modular based design approach.
For ArrayTs
to achieve this new desired level of dependability
and supportability; the new redesign avoided use of, and included removal of all prototype
extension method definitions, throughout the library. Pitfalls for extending prototype method definitions
on a common type, such as the built-in JavaScript
array
type, placed ArrayTs
at great risk for external package repository
integration failures
,
e.g. when consuming other well-known repository library packages from popular package repository sources,
e.g. npm
or bower
.
Importing external repository packages into a project always has the potential to introduce extension method
naming collisions between repository packages. For libraries which do compete with extending the
JavaScript
array
type, with their own
prototype extension method definitions. This is especially true for ArrayTs
,
when considering the following implemented method names, e.g. Clone(), Count(), Contains()
. These
implemented method names, are in fact commonly used names, from within the software development space,
and are likely to be the first method names to collide with other library design implementations. As well,
the Clone()
method does not exist on the IEnumerable<T>
interface for instance, and is custom to this ArrayTs
implementation.
However, there is a very high likelihood, that other common external repository packages have already extended
the JavaScript
array
type with their
own Clone()
extension method, which is why ArrayTs
removed all
prototype-based extension methods and provided cleaner community interoperability through use of a
UMD
modular based design approach.