链表(双向)
@abp/utils 包提供了一个称为双向链表的有用数据结构。它在 Angular(通过导入)和 MVC(通过 abp.utils.common 全局对象)中均可使用。
简单来说,双向链表是一系列记录(也称为节点),这些节点包含前一个节点、后一个节点以及其自身的值(或数据)的信息。
入门指南
要创建双向链表,您只需创建一个新的实例:
在 Angular 中:
import { LinkedList } from '@abp/utils';
const list = new LinkedList();
在 MVC 中:
var list = new abp.utils.common.LinkedList();
构造函数不接受任何参数。
使用方法
如何添加新节点
链表中有多种创建新节点的方法,所有这些方法都作为独立方法提供,同时也通过 add 和 addMany 方法公开。
addHead(value)
addHead(value: T): ListNode<T>
添加一个具有给定值的节点作为列表的第一个节点:
list.addHead('a');
// "a"
list.addHead('b');
// "b" <-> "a"
list.addHead('c');
// "c" <-> "b" <-> "a"
addManyHead(values)
addManyHead(values: T[]): ListNode<T>[]
添加多个具有给定值的节点作为列表的前几个节点:
list.addManyHead(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
list.addManyHead(['x', 'y', 'z']);
// "x" <-> "y" <-> "z" <-> "a" <-> "b" <-> "c"
addTail(value)
addTail(value: T): ListNode<T>
添加一个具有给定值的节点作为列表的最后一个节点:
list.addTail('a');
// "a"
list.addTail('b');
// "a" <-> "b"
list.addTail('c');
// "a" <-> "b" <-> "c"
addManyTail(values)
addManyTail(values: T[]): ListNode<T>[]
添加多个具有给定值的节点作为列表的最后几个节点:
list.addManyTail(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
list.addManyTail(['x', 'y', 'z']);
// "a" <-> "b" <-> "c" <-> "x" <-> "y" <-> "z"
addAfter(value, previousValue [, compareFn])
addAfter(value: T, previousValue: T, compareFn?: ListComparisonFn<T>): ListNode<T>
在具有 previousValue 的第一个节点之后,添加一个具有给定值的节点:
list.addTail('a');
list.addTail('b');
list.addTail('b');
list.addTail('c');
// "a" <-> "b" <-> "b" <-> "c"
list.addAfter('x', 'b');
// "a" <-> "b" <-> "x" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addTail({ x: 1 });
list.addTail({ x: 2 });
list.addTail({ x: 3 });
// {"x":1} <-> {"x":2} <-> {"x":3}
list.addAfter(
{ x: 0 },
2,
(value, searchedValue) => value.x === searchedValue
);
// {"x":1} <-> {"x":2} <-> {"x":0} <-> {"x":3}
默认的比较函数检查深度相等,因此您很少需要传递该参数。
addManyAfter(values, previousValue [, compareFn])
addManyAfter(values: T[], previousValue: T, compareFn?: ListComparisonFn<T>): ListNode<T>[]
在具有 previousValue 的第一个节点之后,添加多个具有给定值的节点:
list.addManyTail(['a', 'b', 'b', 'c']);
// "a" <-> "b" <-> "b" <-> "c"
list.addManyAfter(['x', 'y'], 'b');
// "a" <-> "b" <-> "x" <-> "y" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addManyTail([{ x: 1 },{ x: 2 },{ x: 3 }]);
// {"x":1} <-> {"x":2} <-> {"x":3}
list.addManyAfter(
[{ x: 4 }, { x: 5 }],
2,
(value, searchedValue) => value.x === searchedValue
);
// {"x":1} <-> {"x":2} <-> {"x":4} <-> {"x":5} <-> {"x":3}
默认的比较函数检查深度相等,因此您很少需要传递该参数。
addBefore(value, nextValue [, compareFn])
addBefore(value: T, nextValue: T, compareFn?: ListComparisonFn<T>): ListNode<T>
在具有 nextValue 的第一个节点之前,添加一个具有给定值的节点:
list.addTail('a');
list.addTail('b');
list.addTail('b');
list.addTail('c');
// "a" <-> "b" <-> "b" <-> "c"
list.addBefore('x', 'b');
// "a" <-> "x" <-> "b" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addTail({ x: 1 });
list.addTail({ x: 2 });
list.addTail({ x: 3 });
// {"x":1} <-> {"x":2} <-> {"x":3}
list.addBefore(
{ x: 0 },
2,
(value, searchedValue) => value.x === searchedValue
);
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":3}
默认的比较函数检查深度相等,因此您很少需要传递该参数。
addManyBefore(values, nextValue [, compareFn])
addManyBefore(values: T[], nextValue: T, compareFn?: ListComparisonFn<T>): ListNode<T>[]
在具有 nextValue 的第一个节点之前,添加多个具有给定值的节点:
list.addManyTail(['a', 'b', 'b', 'c']);
// "a" <-> "b" <-> "b" <-> "c"
list.addManyBefore(['x', 'y'], 'b');
// "a" <-> "x" <-> "y" <-> "b" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addManyTail([{ x: 1 },{ x: 2 },{ x: 3 }]);
// {"x":1} <-> {"x":2} <-> {"x":3}
list.addManyBefore(
[{ x: 4 }, { x: 5 }],
2,
(value, searchedValue) => value.x === searchedValue
);
// {"x":1} <-> {"x":4} <-> {"x":5} <-> {"x":2} <-> {"x":3}
默认的比较函数检查深度相等,因此您很少需要传递该参数。
addByIndex(value, position)
addByIndex(value: T, position: number): ListNode<T>
在列表的指定位置添加一个具有给定值的节点:
list.addTail('a');
list.addTail('b');
list.addTail('c');
// "a" <-> "b" <-> "c"
list.addByIndex('x', 2);
// "a" <-> "b" <-> "x" <-> "c"
它也适用于负索引:
list.addTail('a');
list.addTail('b');
list.addTail('c');
// "a" <-> "b" <-> "c"
list.addByIndex('x', -1);
// "a" <-> "b" <-> "x" <-> "c"
addManyByIndex(values, position)
addManyByIndex(values: T[], position: number): ListNode<T>[]
在列表的指定位置添加多个具有给定值的节点:
list.addManyTail(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
list.addManyByIndex(['x', 'y'], 2);
// "a" <-> "b" <-> "x" <-> "y" <-> "c"
它也适用于负索引:
list.addManyTail(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
list.addManyByIndex(['x', 'y'], -1);
// "a" <-> "b" <-> "x" <-> "y" <-> "c"
add(value).head()
add(value: T).head(): ListNode<T>
添加一个具有给定值的节点作为列表的第一个节点:
list.add('a').head();
// "a"
list.add('b').head();
// "b" <-> "a"
list.add('c').head();
// "c" <-> "b" <-> "a"
这是
addHead的替代 API。
add(value).tail()
add(value: T).tail(): ListNode<T>
添加一个具有给定值的节点作为列表的最后一个节点:
list.add('a').tail();
// "a"
list.add('b').tail();
// "a" <-> "b"
list.add('c').tail();
// "a" <-> "b" <-> "c"
这是
addTail的替代 API。
add(value).after(previousValue [, compareFn])
add(value: T).after(previousValue: T, compareFn?: ListComparisonFn<T>): ListNode<T>
在具有 previousValue 的第一个节点之后,添加一个具有给定值的节点:
list.add('a').tail();
list.add('b').tail();
list.add('b').tail();
list.add('c').tail();
// "a" <-> "b" <-> "b" <-> "c"
list.add('x').after('b');
// "a" <-> "b" <-> "x" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.add({ x: 1 }).tail();
list.add({ x: 2 }).tail();
list.add({ x: 3 }).tail();
// {"x":1} <-> {"x":2} <-> {"x":3}
list
.add({ x: 0 })
.after(2, (value, searchedValue) => value.x === searchedValue);
// {"x":1} <-> {"x":2} <-> {"x":0} <-> {"x":3}
这是
addAfter的替代 API。 默认的比较函数检查深度相等,因此您很少需要传递该参数。
add(value).before(nextValue [, compareFn])
add(value: T).before(nextValue: T, compareFn?: ListComparisonFn<T>): ListNode<T>
在具有 nextValue 的第一个节点之前,添加一个具有给定值的节点:
list.add('a').tail();
list.add('b').tail();
list.add('b').tail();
list.add('c').tail();
// "a" <-> "b" <-> "b" <-> "c"
list.add('x').before('b');
// "a" <-> "x" <-> "b" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.add({ x: 1 }).tail();
list.add({ x: 2 }).tail();
list.add({ x: 3 }).tail();
// {"x":1} <-> {"x":2} <-> {"x":3}
list
.add({ x: 0 })
.before(2, (value, searchedValue) => value.x === searchedValue);
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":3}
这是
addBefore的替代 API。 默认的比较函数检查深度相等,因此您很少需要传递该参数。
add(value).byIndex(position)
add(value: T).byIndex(position: number): ListNode<T>
在列表的指定位置添加一个具有给定值的节点:
list.add('a').tail();
list.add('b').tail();
list.add('c').tail();
// "a" <-> "b" <-> "c"
list.add('x').byIndex(2);
// "a" <-> "b" <-> "x" <-> "c"
它也适用于负索引:
list.add('a').tail();
list.add('b').tail();
list.add('c').tail();
// "a" <-> "b" <-> "c"
list.add('x').byIndex(-1);
// "a" <-> "b" <-> "x" <-> "c"
这是
addByIndex的替代 API。
addMany(values).head()
addMany(values: T[]).head(): ListNode<T>[]
添加多个具有给定值的节点作为列表的前几个节点:
list.addMany(['a', 'b', 'c']).head();
// "a" <-> "b" <-> "c"
list.addMany(['x', 'y', 'z']).head();
// "x" <-> "y" <-> "z" <-> "a" <-> "b" <-> "c"
这是
addManyHead的替代 API。
addMany(values).tail()
addMany(values: T[]).tail(): ListNode<T>[]
添加多个具有给定值的节点作为列表的最后几个节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.addMany(['x', 'y', 'z']).tail();
// "a" <-> "b" <-> "c" <-> "x" <-> "y" <-> "z"
这是
addManyTail的替代 API。
addMany(values).after(previousValue [, compareFn])
addMany(values: T[]).after(previousValue: T, compareFn?: ListComparisonFn<T>): ListNode<T>[]
在具有 previousValue 的第一个节点之后,添加多个具有给定值的节点:
list.addMany(['a', 'b', 'b', 'c']).tail();
// "a" <-> "b" <-> "b" <-> "c"
list.addMany(['x', 'y']).after('b');
// "a" <-> "b" <-> "x" <-> "y" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addMany([{ x: 1 }, { x: 2 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":2} <-> {"x":3}
list
.addMany([{ x: 4 }, { x: 5 }])
.after(2, (value, searchedValue) => value.x === searchedValue);
// {"x":1} <-> {"x":2} <-> {"x":4} <-> {"x":5} <-> {"x":3}
这是
addManyAfter的替代 API。 默认的比较函数检查深度相等,因此您很少需要传递该参数。
addMany(values).before(nextValue [, compareFn])
addMany(values: T[]).before(nextValue: T, compareFn?: ListComparisonFn<T>): ListNode<T>[]
在具有 nextValue 的第一个节点之前,添加多个具有给定值的节点:
list.addMany(['a', 'b', 'b', 'c']).tail();
// "a" <-> "b" <-> "b" <-> "c"
list.addMany(['x', 'y']).before('b');
// "a" <-> "x" <-> "y" <-> "b" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addMany([{ x: 1 }, { x: 2 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":2} <-> {"x":3}
list
.addMany([{ x: 4 }, { x: 5 }])
.before(2, (value, searchedValue) => value.x === searchedValue);
// {"x":1} <-> {"x":4} <-> {"x":5} <-> {"x":2} <-> {"x":3}
这是
addManyBefore的替代 API。 默认的比较函数检查深度相等,因此您很少需要传递该参数。
addMany(values).byIndex(position)
addMany(values: T[]).byIndex(position: number): ListNode<T>[]
在列表的指定位置添加多个具有给定值的节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.addMany(['x', 'y']).byIndex(2);
// "a" <-> "b" <-> "x" <-> "y" <-> "c"
它也适用于负索引:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.addMany(['x', 'y']).byIndex(-1);
// "a" <-> "b" <-> "x" <-> "y" <-> "c"
这是
addManyByIndex的替代 API。
如何移除节点
有几种方法可以从链表中移除节点,所有这些方法都作为独立方法提供,同时也通过一个 drop 方法公开。
dropHead()
dropHead(): ListNode<T> | undefined
移除列表中的第一个节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.dropHead();
// "b" <-> "c"
dropManyHead(count)
dropManyHead(count: number): ListNode<T>[]
根据给定的数量移除列表中的前几个节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.dropManyHead(2);
// "c"
dropTail()
dropTail(): ListNode<T> | undefined
移除列表中的最后一个节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.dropTail();
// "a" <-> "b"
dropManyTail(count)
dropManyTail(count: number): ListNode<T>[]
根据给定的数量移除列表中的最后几个节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.dropManyTail(2);
// "a"
dropByIndex(position)
dropByIndex(position: number): ListNode<T> | undefined
从列表中移除指定位置的节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.dropByIndex(1);
// "a" <-> "c"
它也适用于负索引:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.dropByIndex(-2);
// "a" <-> "c"
dropManyByIndex(count, position)
dropManyByIndex(count: number, position: number): ListNode<T>[]
根据给定的数量,从列表中的指定位置开始移除节点:
list.addMany(['a', 'b', 'c', 'd']).tail();
// "a" <-> "b" <-> "c" <-> "d
list.dropManyByIndex(2, 1);
// "a" <-> "d"
它也适用于负索引:
list.addMany(['a', 'b', 'c', 'd']).tail();
// "a" <-> "b" <-> "c" <-> "d
list.dropManyByIndex(2, -2);
// "a" <-> "d"
dropByValue(value [, compareFn])
dropByValue(value: T, compareFn?: ListComparisonFn<T>): ListNode<T> | undefined
从列表中移除第一个具有给定值的节点:
list.addMany(['a', 'x', 'b', 'x', 'c']).tail();
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
list.dropByValue('x');
// "a" <-> "b" <-> "x" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addMany([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
list.dropByValue(0, (value, searchedValue) => value.x === searchedValue);
// {"x":1} <-> {"x":2} <-> {"x":0} <-> {"x":3}
默认的比较函数检查深度相等,因此您很少需要传递该参数。
dropByValueAll(value [, compareFn])
dropByValueAll(value: T, compareFn?: ListComparisonFn<T>): ListNode<T>[]
从列表中移除所有具有给定值的节点:
list.addMany(['a', 'x', 'b', 'x', 'c']).tail();
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
list.dropByValueAll('x');
// "a" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addMany([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
list.dropByValueAll(0, (value, searchedValue) => value.x === searchedValue);
// {"x":1} <-> {"x":2} <-> {"x":3}
默认的比较函数检查深度相等,因此您很少需要传递该参数。
drop().head()
drop().head(): ListNode<T> | undefined
移除列表中的第一个节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.drop().head();
// "b" <-> "c"
这是
dropHead的替代 API。
drop().tail()
drop().tail(): ListNode<T> | undefined
移除列表中的最后一个节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.drop().tail();
// "a" <-> "b"
这是
dropTail的替代 API。
drop().byIndex(position)
drop().byIndex(position: number): ListNode<T> | undefined
从列表中移除指定位置的节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.drop().byIndex(1);
// "a" <-> "c"
它也适用于负索引:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.drop().byIndex(-2);
// "a" <-> "c"
这是
dropByIndex的替代 API。
drop().byValue(value [, compareFn])
drop().byValue(value: T, compareFn?: ListComparisonFn<T>): ListNode<T> | undefined
从列表中移除第一个具有给定值的节点:
list.addMany(['a', 'x', 'b', 'x', 'c']).tail();
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
list.drop().byValue('x');
// "a" <-> "b" <-> "x" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addMany([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
list
.drop()
.byValue(0, (value, searchedValue) => value.x === searchedValue);
// {"x":1} <-> {"x":2} <-> {"x":0} <-> {"x":3}
这是
dropByValue的替代 API。 默认的比较函数检查深度相等,因此您很少需要传递该参数。
drop().byValueAll(value [, compareFn])
drop().byValueAll(value: T, compareFn?: ListComparisonFn<T>): ListNode<T>[]
从列表中移除所有具有给定值的节点:
list.addMany(['a', 'x', 'b', 'x', 'c']).tail();
// "a" <-> "x" <-> "b" <-> "x" <-> "c"
list.drop().byValueAll('x');
// "a" <-> "b" <-> "c"
您可以传递一个自定义的比较函数来检测搜索值:
list.addMany([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]).tail();
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
list
.drop()
.byValueAll(0, (value, searchedValue) => value.x === searchedValue);
// {"x":1} <-> {"x":2} <-> {"x":3}
这是
dropByValueAll的替代 API。 默认的比较函数检查深度相等,因此您很少需要传递该参数。
dropMany(count).head()
dropMany(count: number).head(): ListNode<T>[]
根据给定的数量移除列表中的前几个节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.dropMany(2).head();
// "c"
这是
dropManyHead的替代 API。
dropMany(count).tail()
dropMany(count: number).tail(): ListNode<T>[]
根据给定的数量移除列表中的最后几个节点:
list.addMany(['a', 'b', 'c']).tail();
// "a" <-> "b" <-> "c"
list.dropMany(2).tail();
// "a"
这是
dropManyTail的替代 API。
dropMany(count).byIndex(position)
dropMany(count: number).byIndex(position: number): ListNode<T>[]
根据给定的数量,从列表中的指定位置开始移除节点:
list.addMany(['a', 'b', 'c', 'd']).tail();
// "a" <-> "b" <-> "c" <-> "d
list.dropMany(2).byIndex(1);
// "a" <-> "d"
它也适用于负索引:
list.addMany(['a', 'b', 'c', 'd']).tail();
// "a" <-> "b" <-> "c" <-> "d
list.dropMany(2).byIndex(-2);
// "a" <-> "d"
这是
dropManyByIndex的替代 API。
如何查找节点
有几种方法可以在链表中查找特定的节点。
head
head: ListNode<T> | undefined;
引用列表中的第一个节点。
tail
tail: ListNode<T> | undefined;
引用列表中的最后一个节点。
length
length: number;
列表中节点的总数。
find(predicate)
find(predicate: ListIteratorFn<T>): ListNode<T> | undefined
查找列表中第一个与给定谓词匹配的节点:
list.addManyTail(['a', 'b', 'b', 'c']);
// "a" <-> "b" <-> "b" <-> "c"
var found = list.find(node => node.value === 'b');
/*
found.value === "b"
found.previous.value === "a"
found.next.value === "b"
*/
findIndex(predicate)
findIndex(predicate: ListIteratorFn<T>): number
查找列表中第一个与给定谓词匹配的节点的位置:
list.addManyTail(['a', 'b', 'b', 'c']);
// "a" <-> "b" <-> "b" <-> "c"
var i0 = list.findIndex(node => node.next && node.next.value === 'b');
var i1 = list.findIndex(node => node.value === 'b');
var i2 = list.findIndex(node => node.previous && node.previous.value === 'b');
var i3 = list.findIndex(node => node.value === 'x');
/*
i0 === 0
i1 === 1
i2 === 2
i3 === -1
*/
get(position)
get(position: number): ListNode<T> | undefined
查找并返回列表中特定位置的节点:
list.addManyTail(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
var found = list.get(1);
/*
found.value === "b"
found.previous.value === "a"
found.next.value === "c"
*/
indexOf(value [, compareFn])
indexOf(value: T, compareFn?: ListComparisonFn<T>): number
查找列表中第一个具有给定值的节点的位置:
list.addManyTail(['a', 'b', 'b', 'c']);
// "a" <-> "b" <-> "b" <-> "c"
var i0 = list.indexOf('a');
var i1 = list.indexOf('b');
var i2 = list.indexOf('c');
var i3 = list.indexOf('x');
/*
i0 === 0
i1 === 1
i2 === 3
i3 === -1
*/
您可以传递一个自定义的比较函数来检测搜索值:
list.addManyTail([{ x: 1 }, { x: 0 }, { x: 2 }, { x: 0 }, { x: 3 }]);
// {"x":1} <-> {"x":0} <-> {"x":2} <-> {"x":0} <-> {"x":3}
var i0 = indexOf(1, (value, searchedValue) => value.x === searchedValue);
var i1 = indexOf(2, (value, searchedValue) => value.x === searchedValue);
var i2 = indexOf(3, (value, searchedValue) => value.x === searchedValue);
var i3 = indexOf(0, (value, searchedValue) => value.x === searchedValue);
var i4 = indexOf(4, (value, searchedValue) => value.x === searchedValue);
/*
i0 === 0
i1 === 2
i2 === 4
i3 === 1
i4 === -1
*/
默认的比较函数检查深度相等,因此您很少需要传递该参数。
如何检查所有节点
有几种方法可以遍历或显示链表。
forEach(iteratorFn)
forEach(iteratorFn: ListIteratorFn<T>): void
对链表中从头到尾的所有节点运行一个函数:
list.addManyTail(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
list.forEach((node, index) => console.log(node.value + index));
// 'a0'
// 'b1'
// 'c2'
*[Symbol.iterator]()
链表是可迭代的。换句话说,您可以在其上使用诸如 for...of 之类的方法。
list.addManyTail(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
for(const node of list) { /* ES6 for...of 语句 */
console.log(node.value);
}
// 'a'
// 'b'
// 'c'
toArray()
toArray(): T[]
将链表转换为值的数组:
list.addManyTail(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
var arr = list.toArray();
/*
arr === ['a', 'b', 'c']
*/
toNodeArray()
toNodeArray(): ListNode<T>[]
将链表转换为节点的数组:
list.addManyTail(['a', 'b', 'c']);
// "a" <-> "b" <-> "c"
var arr = list.toNodeArray();
/*
arr[0].value === 'a'
arr[1].value === 'a'
arr[2].value === 'a'
*/
toString([mapperFn])
toString(mapperFn: ListMapperFn<T> = JSON.stringify): string
将链表转换为表示节点及其关系的字符串:
list.addManyTail(['a', 2, 'c', { k: 4, v: 'd' }]);
// "a" <-> 2 <-> "c" <-> {"k":4,"v":"d"}
var str = list.toString();
/*
str === '"a" <-> 2 <-> "c" <-> {"k":4,"v":"d"}'
*/
您可以传递一个自定义的映射函数,以便在字符串化之前映射值:
list.addMany([{ x: 1 }, { x: 2 }, { x: 3 }, { x: 4 }, { x: 5 }]).tail();
// {"x":1} <-> {"x":2} <-> {"x":3} <-> {"x":4} <-> {"x":5}
var str = list.toString(value => value.x);
/*
str === '1 <-> 2 <-> 3 <-> 4 <-> 5'
*/
API
类
LinkedList
export class LinkedList<T = any> {
// 属性和方法如上所述
}
ListNode
export class ListNode<T = any> {
next: ListNode | undefined;
previous: ListNode | undefined;
constructor(public readonly value: T) {}
}
ListNode 是 LinkedList 中为每个记录存储的节点。
value是存储在节点中的值,通过构造函数传递。next指向列表中的下一个节点。previous指向列表中的上一个节点。
list.addManyTail([ 0, 1, 2 ]);
console.log(
list.head.value, // 0
list.head.next.value, // 1
list.head.next.next.value, // 2
list.head.next.next.previous.value, // 1
list.head.next.next.previous.previous.value, // 0
list.tail.value, // 2
list.tail.previous.value, // 1
list.tail.previous.previous.value, // 0
list.tail.previous.previous.next.value, // 1
list.tail.previous.previous.next.next.value, // 2
);
类型
ListMapperFn
type ListMapperFn<T = any> = (value: T) => any;
此函数在 toString 方法中使用,用于在生成列表的字符串表示之前映射节点值。
ListComparisonFn
type ListComparisonFn<T = any> = (nodeValue: T, comparedValue: any) => boolean;
此函数在基于比较值添加、移除和查找节点时使用。
ListIteratorFn
type ListIteratorFn<T = any, R = boolean> = (
node: ListNode<T>,
index?: number,
list?: LinkedList,
) => R;
此函数在遍历列表以对每个节点执行某些操作或查找节点时使用。
抠丁客


