![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
@mrtujiawei/utils
Advanced tools
使用 npm:
$ npm install @mrtujiawei/utils
使用 yarn:
$ yarn add @mrtujiawei/utils
使用 unpkg CDN:
<!-- 开发环境 -->
<script src="https://unpkg.com/@mrtujiawei/utils"></script>
<!-- 生产环境 -->
<script src="https://unpkg.com/@mrtujiawei/utils/dist/umd/index.min.js"></script>
使用 jsdelivr CDN:
<!-- 开发环境 -->
<script src="https://cdn.jsdelivr.net/npm/@mrtujiawei/utils/dist/umd/index.js"></script>
<!-- 生产环境 -->
<script src="https://cdn.jsdelivr.net/npm/@mrtujiawei/utils/dist/umd/index.min.js"></script>
直接在浏览器中使用
<script src="https://cdn.jsdelivr.net/npm/@mrtujiawei/utils"></script>
<script>
const { Stack } = TUtils.Stack;
</script>
通过 CommonJS 引入
const { Stack } = require('@mrtujiawei/utils');
或者
const utils = require('@mrtujiawei/utils');
const Stack = utils.Stack;
通过 ESModule 引入
import { Stack } from '@mrtujiawei/utils';
或者
import utils from '@mrtujiawei/utils';
const Stack = utils.Stack;
堆栈(链表实现)
引入
import { Stack } from '@mrtujiawei/utils';
实例化
const stack = new Stack();
获取当前元素个数
stack.size;
判断栈是否为空
stack.isEmpty();
判断栈是否非空
stack.isNotEmpty();
入栈
push
多个元素stack.push(value);
出栈
pop
会抛出StackEmptyErrorstack.pop();
获取栈顶元素
peak
会抛出StackEmptyErrorstack.peak();
异常
// 栈为空时获取元素
Stack.StackEmptyError
队列(双端链表实现)
引入
import { Queue } from '@mrtujiawei/utils';
实例化
const queue = new Queue();
获取当前元素个数
queue.size;
队首元素
front
会抛出QueueEmptyErrorqueue.front;
队尾元素
tail
会抛出QueueEmptyErrorqueue.tail;
判断队列是否为空
queue.isEmpty();
入队
enqueue
多个元素queue.enqueue(value);
出队
dequeue
会抛出QueueEmptyErrorqueue.dequeue();
异常
// 队列为空时仍获取元素
Queue.QueueEmptyError
双端队列(双端链表实现)
引入
import { Deque } from '@mrtujiawei/utils';
实例化
const deque = new Deque();
从队头入队
deque.pushFront(value);
从队尾入队
deque.pushBack(value);
判断队列是否为空
deque.isEmpty();
判断队列是否非空
deque.isNotEmpty();
获取队列元素个数
deque.getSize();
获取队首元素
getFront
会抛出DequeEmptyErrordeque.getFront();
获取队尾元素
getBack
会抛出DequeEmptyErrordeque.getBack();
队列转数组
deque.toArray();
从队头出队
popFront
会抛出DequeEmptyErrordeque.popFront();
从队尾出队
popBack
会抛出DequeEmptyErrordeque.popBack();
清空队列
deque.clear();
异常
// 队列未空时仍获取元素
Deque.DequeEmptyError;
单向链表
引入
import { LinkedList } from '@mrtujiawei/utils';
实例化
const list = new LinkedList();
获取当前元素个数
list.getSize();
链表是否为空
list.isEmpty();
链表是否非空
list.isNotEmpty();
清空链表
list.clear();
从链表头部插入
list.insertFirst(value);
指定下标处插入
0 <= index <= list.getSize()
InvalidIndexError
list.insertAt(index, value);
链表尾部插入
list.insertLast(value);
移除头结点
removeFirst
会抛出LinkedListEmptyError
list.removeFirst();
移除尾节点
removeLast
会抛出LinkedListEmptyError
list.removeLast();
移除指定下标的节点
InvalidIndexError
list.removeAt(index);
复制链表
list.clone(oldList);
遍历链表
list.forEach((value, index, context) => {
// TODO ...
});
过滤出符合条件的新链表
true
保留, false
不保留list.filter((value, index, context) => {
// TODO ...
});
查找第一个满足条件的值
true
时,返回对应的value
list.find((value, index, context) => {
// TODO
});
获取第一个节点值
getFirst
会抛出LinkedListEmptyError
list.getFirst();
转化成数组
list.toArray();
从数组创建链表
let list = LinkedList.fromArray(arr);
for..of
遍历
for (const value of list) {
// TODO
}
异常
// 为空时获取元素
LinkedList.LinkedListEmptyError;
// 传入不合理的下标
LinkedList.InvalidIndexError;
双向链表
引入
import { DoublyLinkedList } from '@mrtujiawei/utils';
实例化
const list = new DoublyLinkedList();
清空链表
list.clear();
连接两个链表
const newList = list.concat(otherList);
是否包含
list.contains(value);
过滤出符合条件的新链表
true
保留, false
不保留const newList = list.filter((value, index, context) => {
// TODO
});
查找第一个满足要求的元素
const value = list.find((value, index, context) => {
// TODO
});
查找第一个满足要求的元素下标
const index = list.findIndex((value, index, context) => {
// TODO
});
forEach遍历
list.forEach((value, index, context) => {
// TODO
});
获取指定下标的值
InvalidIndexError
list.get(index);
获取链表中的第一个值
EmptyError
const value = list.getFirst();
获取链表中的最后一个值
EmptyError
const value = list.getLast();
是否包含某个值
list.includes();
第一个等于指定值的下标
index = -1
const index = list.indexOf(value);
判断链表是否为空
list.isEmpty();
根据参数合并成字符串
const result = list.join(',');
最后一个满足条件的元素下标
const index = lastIndexOf(value);
映射成一个新的链表
const newList = list.map(value => {
// TODO
return newValue;
});
移除最后一个元素
EmptyError
const value = list.pop();
向尾部添加
list.push(value);
元素汇总
list.reduce((previousValue, currentValue, index, context) => {
// TODO
return nextValue;
});
元素反向汇总
list.reduceRight((previousValue, currentValue, index, context) => {
// TODO
return nextValue;
});
移除指定下标的元素
InvalidIndexError
const value = list.remove(index);
反转链表
list.reverse();
设置指定位置的值
InvalidIndexError
list.set(index, value);
移除第一个元素
EmptyError
list.shift();
获取链表长度
list.size();
复制链表中的一段
list.slice(startIndex, endIndex);
查找是否有满足条件的值
list.some((value, index, context) => {
// TODO
return false || true;
})
转化成数组
const arr = list.toArray();
头部添加
list.unshift(value);
链表排序
sort((a, b) => number);
转化成字符串
const str = list.toString();
移除所有满足条件的元素
const removeSize = list.remove((value, index, context) => {
// TODO
return true || false;
});
反向遍历
list.forEachReverse((value, index, context) => {
// TODO
});
反向查找
const value = list.findReverse((value, index, context) => {
// TODO
return true || false;
});
for..of 遍历
for (const value of list) {
// TODO
}
异常
// 下标异常
DoublyLinkedList.InvalidIndexError
// 链表为空
DoublyLinkedList.EmptyError
引入
import { Skiplist } from '@mrtujiawei/utils';
初始化
const list = new Skiplist((a, b) => a - b);
获取长度
list.length;
查找是否存在指定值
list.search(value);
获取第一个元素
const firstValue = list.getFirst();
插入元素
list.insert(value);
移除元素
list.remove(value);
转化成数组
list.toArray();
遍历
list.forEach((value, index, context) => {
// TODO
});
for..of 遍历
for (const value of list) {
// TODO
}
堆
引入
import { Heap } from '@mrtujiawei/utils';
实例化(小顶堆)
const heap = new Heap((a, b) => a - b);
获取堆中元素数量
heap.size;
判断堆是否为空
heap.isEmpty();
判断堆是否非空
Heap.isNotEmpty();
获取堆顶元素
peak
会抛出Heap.HeapEmptyErrorheap.peak();
插入元素
heap.insert(value);
移除堆顶元素
peak
会抛出Heap.HeapEmptyErrorheap.remove();
替换堆顶元素
heap.replaceTop(0);
异常
// 堆为空时获取元素
Heap.HeapEmptyError
// 比较器错误
Heap.CompareInvalidError
并查集
引入
import { UnionFind } from '@mrtujiawei/utils';
实例化
IllegaleArgumentException
const uf = new UnionFind(capacity);
合并集合
uf.union(u1, u2);
查找集合的根节点
uf.find(u);
是否属于同一个集合
uf.isBelongSameUnion(u1, u2);
二叉搜索树
import { BinarySearchTree } from '@mrtujiawei/utils';
const bTree = new BinarySearchTree((a, b) => a - b, []);
bTree.append(1);
bTree.append(2);
bTree.append(3);
bTree.append(4);
// 执行4次
// 1, 2, 3, 4
bTree.inorderTraversal((value) => {
console.log(value);
});
bTree.getMin(); // 1
bTree.getMax(); // 4
bTree.toArray(); // [1, 2, 3, 4]
bTree.clear(); // []
平衡二叉搜索树
引入
import { AVLTree } from '@mrtujiawei/utils';
实例化
const tree = new AVLTree((a, b) => a - b);
添加节点
key
时会抛出DuplicateValueError
tree.append(key, value);
根据 key
移除节点
true
时删除成功,否则失败tree.remove(key);
判断是否存在key
tree.has(key);
获取key
对应的value
const value = tree.getValue(key);
获取节点个数
const size = tree.getSize();
清空树
tree.clear();
异常
// 插入已经存在的key
AVLTree.DuplicateValueError
前缀树(支持插入相同单词)
引入
import { Trie } from '@mrtujiawei/utils';
实例化
const trie = new Trie();
从数组实例化
const trie = Trie.fromArray(words);
获取字典树中有多少个单词
const count = trie.getWordCount();
插入单词
trie.insert(word);
判断是否存在该单词
trie.search(word);
判断指定前缀的单词是否存在
trie.startsWith(prefix);
移除指定单词
false
移除失败:单词不存在true
移除成功trie.remove(word);
遍历
trie.forEach((word) => {
// TODO
});
转化成数组
const words = trie.toArray();
清空前缀树
trie.clear();
异步流程加锁
import { Lock, sleep } from '@mrtujiawei/utils';
const lock = new Lock(1);
/**
* 异步任务只有等上次任务结束后才会开始执行下一个异步任务
*/
const run = async (value, timeout) => {
try {
await lock.lock();
// 异步任务
await sleep(timeout);
console.log(value);
} finally {
lock.unlock();
}
};
run(0, 1000);
run(1, 100);
run(2, 0);
output: 0 1 2
任务队列,主要是用来执行单任务
职责链
日期时间处理类
解析时间太复杂,没做
import { DateTimeTool } from '@/mrtujiawei/utils';
DateTimeTool.timeFormat(new Date(), ':'); // hh:mm:ss
DateTimeTool.dateFormat(new Date(), '-'); // yyyy-mm-dd
DateTimeTool.dateTimeFormat(new Date()); // yyyy-mm-dd hh:mm:ss
DateTimeTool.getNthDayBefore(2); // 获取n天以前时间和当前日期时间
DateTimeTool.getNthHourBefore(2); // 获取n小时之前到当前时间
DateTimeTool.getNthMonthBefore(1); // 获取n月以前时间到当前月时间
DateTimeTool.toDayBegin(new Date()); // 设置到当前天的开始 00:00:00.000
DateTimeTool.toDayEnd(new Date()); // 设置到当前天的结束 23:59:59.999
DateTimeTool.isLeapYear(new Date()); // 是否是闰年
DateTimeTool.diffTimestamp(new Date(), new Date()); // 时间戳差值
DateTimeTool.diffSeconds(new Date(), new Date()); // 秒差值
DateTimeTool.diffMinutes(new Date(), new Date()); // 分钟差值
DateTimeTool.diffHours(new Date(), new Date()); // 小时差值
DateTimeTool.diffDays(new Date(), new Date()); // 天差值
DateTimeTool.addDays(new Date(), 10); // 日期往后加10天
DateTimeTool.timestampToTime(123); // hh:mm:ss
DateTimeTool.timestampToDate(123); // yyyy-mm-dd
DateTimeTool.timestampToDateTime(123); // yyyy-mm-dd hh:mm:ss
DateTimeTool.getCurrentWeek(new Date()); // 获取当周的日期范围
倒计时
import { CountDown } from '@mrtujiawei/utils';
const countDown = new CountDown('默认信息');
const callback = countDown.subscribe((data) => {
// 结束倒计时
if (data.done) {
data.message; // 默认信息
} else {
data.message; // 倒计时数字 60, 59...
}
});
countDown.start({
start: 60,
end: 0,
timeout: 1,
});
// 取消其中的一个订阅
countDown.unsubscribe(callback);
// 清空所有订阅函数
countDown.clear();
分页
import { Pagination } from '@mrtujiawei/utils';
const tableData = {
pageNum: 1,
pageSize: 10,
tableData: [],
total: 0,
};
const pagination = new Pagination(tableData);
pagination.subscribe((tableData) => {
console.log(tableData);
});
pagination.setPageSize(20);
const key = 'key';
pagination.setOrder(key); // 设置排序
pagination.sort(); // 重新排序
pagination.to(2); // 跳到第二页
日志记录
import { Logger } from '@mrtujiawei/utils';
const logger = Logger.getLogger();
const callback = logger.subscribe((message) => {
console.log(message);
});
logger.setLevel(Logger.LOG_LEVEL.ALL);
logger.trace('info');
logger.info('info');
logger.debug('debug');
logger.warn('warn');
logger.error('error');
logger.fatal('fatal');
logger.unsubscribe(callback);
事件发射
const events = new Events();
const listener = events.on('start', (...data) => {
console.log(data);
});
events.once('start', (...data) => {
console.log(data);
});
events.emit('start', 1, 2, 3);
// 1 2 3
// 1 2 3
events.off('start', listener);
events.emit('start');
// 没有输出
随机
import { Random } from '@mrtujiawei/utils';
Random.getRandomNumber(100, 1000); // [100, 1000)
Random.getRandomBoolean(); // true | false
Random.getRandomUppercaseLetter(); // [A-Z]
Random.getRandomUppercaseString(n); // [A-Z]{n}
Random.getRandomLowercaseLetter(); // [a-z]
Random.getRandomLowercaseString(n); // [a-z]{n}
Random.getRandomAlphabetString(n); // [a-zA-Z]{n}
Random.getRandomString(n); // [a-zA-Z0-9]{n}
Random.getRandomID(); // ********-**************-************
优先队列
import { PriorityQueue } from '@mrtujiawei/utils';
// 数字越小优先级越高
const pq = new PriorityQueue((a, b) => a - b);
pq.isEmpty(); // true
pq.enqueue(5);
pq.isEmpty(); // false
pq.enqueue(3);
pq.enqueue(1);
pq.enqueue(2);
pq.peak(); // 1
pq.dequeue(); // 1
pq.dequeue(); // 2
翻转数组中的某一段
import { reverseRange } from '@mrtujiawei/utils';
const arr = [1, 2, 3];
reverseRange(arr, 1, 3); // [1, 3, 2]
交换数组中的两个元素
import { swap } from '@mrtujiawei/utils';
const arr = [1, 2, 3];
swap(arr, 1, 2); // [1, 3, 2];
延时一段时间
// 延时 1s
await sleep(1);
防抖
import { debounce } from '@mrtujiawei/utils';
const listener = debounce((event) => {
console.log(event);
}, 500);
addEventListener('scroll', listener, {
passive: true,
});
节流
import { throttle } from '@mrtujiawei/utils';
const options = {
// 100ms以内只触发一次
timeout: 100,
// 第一次是否直接触发
// false 100ms以后才会触发
leading: true,
};
const listener = throttle((data) => {
console.log(data);
}, { timeout: 100, leading: true });
addEventListener('scroll', listener);
是否是整数, 实际值
import { isInteger } from '@mrtujiawei/utils';
isInteger(0); // true
isInteger('1'); // true
isInteger(1.1); // false
isInteger('a'); // false
是否是自然数
import { isNaturalNumber } from '@mrtujiawei/utils';
isNaturalNumber('123'); // true
isNaturalNumber(-1); // false
isNaturalNumber('a'); // false
判断是否是promise
import { isPromise } from '@mrtujiawei/utils';
const promise = new Promise(() => {});
const number = 0;
isPromise(promise); // true
isPromise(number); // false
重试
import { retry } from '@mrtujiawei/utils';
// 如果回调执行失败,会重复执行直到成功或者执行次数超过10次
const listener = retry((data) => {
console.log(data);
}, 9);
listener(1);
重入
import { reentrant, sleep, } from '@mrtujiawei/utils';
const func = reentrant(async (value) => {
await sleep(1);
return `#{value}#`;
});
const run = (data) => {
const result = await func(data);
console.log(result);
};
// 无输出
run(100);
run(200); // #200#
二分查找第一个满足条件的下标
import { findFirstIndex, } from '@mrtujiawei/utils';
findFirstIndex([1, 2, 3, 4, 5]);
对象转字符串,不是json
import { objectToString } from '@mrtujiawei/utils';
objectToString('asf'); // "asf"
objectToString([1, 2]); // [1, 2, length: 2]
判断两个值是否相同,两个值都是 NaN 也是 true
type isSame = (value1: unknown, value2: unknown) => boolean;
import { isSame } from '@mrtujiawei/utils';
isSame(NaN, NaN); // true
isSame(null, null); // true
isSame('123', 123); // false
isSame(undefined, undefined); // true
FAQs
The npm package @mrtujiawei/utils receives a total of 184 weekly downloads. As such, @mrtujiawei/utils popularity was classified as not popular.
We found that @mrtujiawei/utils demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.