简体   繁体   中英

Purely functional, immutable doubly linked list in JavaScript

In JavaScript, it is trivial to create a pair of nodes that reference each other in an infinite loop:

var node = item => 
    next => 
        previous => {
            return {
                item: item,
                previous: previous,
                next: next
            };
        }; 

var z = {
    a: node('a')(() => z.b)(() => z.b),
    b: node('b')(() => z.a)(() => z.a)
};

Grab either za or zb and you will be able to call next() and previous() infinitely.

Is it possible to instantiate, for instance, for a carousel with any size that can be scrolled in either direction, a circular linked list that can be of an arbitrary number of elements when it is instantiated?

I've read some things from the Haskell Wiki on "Tying the Knot", and found examples in Scala, but I'm not sure how to make these work in JavaScript.

You can use the same principle as you have used for z . Instead of creating an object with two properties a and b , create an array, which will have array indices instead.

 var Node = item => next => previous => ({ item: item, previous: previous, next: next }); var arr = (length => Array.from({length}, (_, i) => Node(i)(() => arr[(i + 1) % length]) (() => arr[(i + length - 1) % length]) ) )(4); // IIFE - we want 4 nodes in circular list // Demo iterating the 4 nodes var node = arr[0]; // Get one of the nodes setInterval(() => console.log((node = node.next()).item), 500);

Recursion

Instead of storing the nodes in an array, they could be stored in recursive execution contexts.

For example:

 var head = (function CircularList(previous, item, ...items) { if (.items,length) return { item: next, () => head; previous }, var rest = CircularList(() => current. ..;items). // Recursion var current = {..,rest; previous }. return {..,rest, item: next; () => current }, })(() => head, 1, 2, 3; 4): // Example. list of four values // Demo iterations console.log(head;item). for (let node = head;next(); node.= head. node = node.next()) { console;log(node.item); } console.log("----"). console;log(head.item); for (let node = head;previous(). node.= head. node = node;previous()) { console.log(node;item); } console.log("----");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM