npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

generic-linked-list

v2.0.1

Published

Linked Lists using Generics

Downloads

241

Readme

Single-Linked List Using Generics

About

This project implements a Single-Linked List that you can use for a linked list of any data type.

The motivations for this project are:

  • to provide a mostly drop-in replacement for Arrays (see below);
  • that works with any data type;
  • written in a strongly-typed language (TypeScript);
  • that is well-documented;
  • and is well-tested;
  • and is suitable for professional Software Engineering projects.

The project focuses on backend development with NodeJs in mind. However, as it is written in TypeScript (which compiles to JavaScript), you can use it in code targeting browsers.

What's wrong with Arrays?

Arrays are a powerful and well-used data structure in both JavaScript and TypeScript.

However, some array operations are O(n) in Time Complexity. These include shift and unshift.

This means working with large datasets is usually faster with a Linked List compared to an Array.

Time-space trade off

Linked lists are a classic time-space tradeoff when compared with arrays for some operations.

Because a linked list has a "pointer" to the next element in the list, each element in the list uses slightly more memory than the same list stored in an array.

But, that extra memory provides huge speed improvement for some operations.

Most linked list operations are similar in speed to array.

Operations faster than array

  • shift
  • unshift
  • splice

These operations are many hundreds to thousands of times faster than an array!

If you're working with lists of 10's or 100's of thousands of elements, and you need these operations, you should consider a linked list instead of an array for storing those elements.

Operations slower than array

Some linked list operations are significantly slower than an array because the list must be traversed from beginning to some point in the list (usually all the way to the end).

  • at
  • fill
  • lastIndexOf
  • pop
  • slice

If your use case requires these operations on a large lists, then you should consider using a different data structure (such as Array).

Operations not implemented

The following operations cannot be implemented efficiently in a singly-linked list and are not implemented.

These can be implemented in a doubly-linked list, and such a data structure is planned for a future release of this package.

  • reverse
  • reduceRight

Code size

The majority of the code in this package is contained in unit tests.

Code sizes:

  • The compiled Typescript is 7 kilobytes when minified.
  • The full JavaScript code including comments is around 40 kilobytes.
  • The unit tests are around 120 kilobytes.

Getting started

  1. Import the library.
  2. Create your linked list.
  3. Use it!

Add to your project

With yarn:

yarn add generic-linked-list --save

With npm:

npm --save-prod i generic-linked-list

Run the examples

Plain JavaScript:

$ node dist/examples/plainjs.js
A simple numeric list is [ 0, 1, 2 ]

Typescript (directly):

$ ts-node src/examples/example.ts a b c 
Your linked list is a,b,c

A list of numbers expanded using spread syntax [ 1, 2, 3 ]
The same list converted to a string [1,2,3]

Let us build a list of Person objects...
A list of people expanded using spread syntax { name: 'John', age: 12, parent: { name: 'John', age: 42 } } { name: 'Kylie', age: 14 }
The same list converted to a string {"name":"John","age":12,"parent":{"name":"John","age":42}},{"name":"Kylie","age":14}

Here's the array after converting the people list to an array:
[
  { name: 'John', age: 12, parent: { name: 'John', age: 42 } },
  { name: 'Kylie', age: 14 }
]

Typescript (compiled):

$ yarn build
$ node dist/examples/example.js a b c

Same output as above.

TypeScript examples

Example 1

import { LinkedList } from 'generic-linked-list';

const numList = new LinkedList([1, 2, 3]);
console.log(...numList);
console.log(numList.toString());

Expected output:

[ 1, 2, 3 ]
[1,2,3]

Example 2

import { LinkedList } from 'generic-linked-list';

type Person = { name: string, age: number; parent?: Person };
const peopleList = new LinkedList<Person>();
peopleList.push(
  {name: 'John', age: 12, parent: {name: 'John', age: 42}},
  {name: 'Kylie', age: 14}
);
console.log(...peopleList);
console.log(peopleList.toString());

Expected output:

{ name: 'John', age: 12, parent: { name: 'John', age: 42 } } { name: 'Kylie', age: 14 }
{"name":"John","age":12,"parent":{"name":"John","age":42}},{"name":"Kylie","age":14}

Example 3 (plain JavaScript)

const LinkedList = require('generic-linked-list').LinkedList;

const sampleList = new LinkedList([0, 1, 2]);
console.log(`Your linked list is ${[...sampleList]}`);

Expected output:

Your linked list is 0,1,2

Where to next?

The documentation is generated using TypeDoc using comments in the source code.

The project's GitHub page contains the documentation and is the best place to start.

Example code

To access example code that actually runs:

  • download the package;
  • look in the src/examples folder.

Version 2 Compatibility

Version 2 aims to be even closer to a drop-in replacement for Array.

Version 2 implements additional constructor options to make LinkedList more similar to Array construction. It also clarifies the semantics of the from method.

In particular, the constructor now implements both a length and an item list constructor.

Version 2 Constructor

This means that the following code in Version 1:

const list = new LinkedList<number>([1, 2]);

must be changed to:

const list = new LinkedList<number>(...[1, 2]);

or

const list = new LinkedList<number>(1, 2);

If you want to build a LinkedList from an array with the spread operator, use the from method:

const list = LinkedList.from([1, 2]);

Version 2 from method

LinkedList.from behaves differently to Array when called with non-array constructors. See the documentation for Array about this.

Version History

| Version | Date | Description | |---------|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 2.0.1 | 11-Dec-2022 | Some documentation improvements. | | 2.0.0 | 11-Dec-2022 | Version 2 is mostly compatible with version 1, except for the following:* Constructor and from enhancements may require some refactoring of your existing version 1 code.* The push method also accepts an iterator. Array.push does not support this. * Added support for negative indexes in these methods:atindexOfincludesslice* Added the following methods:entriesflatflatMapfromgrowjoinkeyskeysAsListlastIndexOfofmappopreducesplicetruncate | | 1.1.3 | 11-Nov-2022 | Documentation and test improvements. | | 1.1.2 | 15-Oct-2022 | Added missing index.ts file. | | 1.1.1 | 15-Oct-2022 | Test improvements. | | 1.1.0 | 15-Oct-2022 | Added slice and end methods. | | 1.0.3 | 22-Sep-2022 | Documentation and test improvements. | | 1.0.1 | 17-Sep-2022 | Documentation improvements. | | 1.0.0 | 17-Sep-2022 | First "official" release. |

Node.js version

The project was developed in NodeJs version 14.15.4 and should run seamlessly in any later version of Node.js.

TypeScript version

The project was developed with TypeScript 4.5.5 and should compile seamlessly in any later version of TypeScript.

About the author

Russell Robinson is a Software Engineer with decades of experience across a range of industries.

He lives in Melbourne, Australia and can be contacted via email ([email protected]).