Skip to content

Commit

Permalink
go to Chiang Mai
Browse files Browse the repository at this point in the history
  • Loading branch information
any committed Dec 13, 2024
1 parent 599b0c4 commit 3fb996b
Show file tree
Hide file tree
Showing 23 changed files with 395 additions and 55 deletions.
40 changes: 40 additions & 0 deletions codes/js/std/Array/add&delete.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* ===add===
* push* 尾部位置
* unshift* 头部位置
* ===delete===
* pop* 尾部位置
* shift* 头部位置
* arr.length = n 长度修改(可清空)
* ===特殊===
* splice* 任意位置的删除与插入
* toSpliced 函数式 splice 方法
*/

const { push, unshift, fill } = Array;

test("push&unshift用法", () => {
const arr = [];
arr.push("end");
arr.unshift("start");
expect(arr[0]).toBe("start");
expect(arr[arr.length - 1]).toBe("end");
});

test("pop&shift用法", () => {
const arr = [1, 2, 3, 4, 5];
arr.shift();
arr.shift();
arr.pop();
arr.pop();
expect(arr).toEqual([3]);
arr.length = 0;
expect(arr).toEqual([]);
});

test("toSpliced用法", () => {
const arr = [0, 1, 2, 3, 4, 5];
const arr1 = arr.toSpliced(1, 3, "x", "y");
expect(arr).toEqual([0, 1, 2, 3, 4, 5]); // 没变
expect(arr1).toEqual([0, "x", "y", 4, 5]); // 首先删除 3 个元素,然后插入 2 个元素
});
67 changes: 67 additions & 0 deletions codes/js/std/Array/iterate.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* ===lang:iterate===
* forEach 遍历
* map 遍历返回新数组
* every 遍历且所有项都通过测试
* some 遍历且有项通过测试
* filter 遍历且过滤数组
* reduce/reduceRight 遍历且归因
*/
const { forEach } = Array.prototype;
test("forEach是无法中途退出的全量迭代", () => {
const array = [1, 2, 3, 4, 5, 6];
let value = 0;
array.forEach((item, index) => {
// js引擎不报错,jest报错
// if(index === 1) continue;
// if(index === 2) break;
value++;
});
expect(value).toBe(6);
});
test("map是无法中途退出的全量迭代", () => {
const array = [1, 2, 3];
const result = array.map((item) => item);
expect(result).toEqual([1, 2, 3]);
});
test("every即每一轮都返回 true 则最终返回 true,遇false会终止迭代并返回 false", () => {
const arr = [1, 2, 3];
let count = 0;
arr.every((item) => {
count++;
if (item === 2) return false;
return true;
});
expect(count).toBe(2);
});
test("some即只要有一轮返回 true 则最终返回 true,遇 true会终止迭代并返回 true", () => {
const arr = [1, 2, 3];
let count = 0;
arr.some((item) => {
count++;
if (item === 2) return true;
return false;
});
expect(count).toBe(2);
});
test("filter即筛选,用法是遇false 则不返回,是中途无法退出的全量迭代,", () => {
const array = [1, 2, 3, 4, 5];
let count = 0;
const result = array.filter((item) => {
count++;
return item < 3;
});
expect(result).toEqual([1, 2]);
expect(count).toBe(5);
});
test("reduce向左汇总,即遍历方向向右", () => {
const initialValue = 0;
const callbackFn = function (accumulator, currentValue, currentIndex, array) {
return Math.max(accumulator, currentValue);
};
const arr = [10, 100];
expect(arr.reduce(callbackFn, initialValue)).toBe(100);
});
test("reduceRight向右汇总,即遍历方向向左", () => {
// TODO
});
49 changes: 49 additions & 0 deletions codes/js/std/Array/modify.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* ===modify===
* fill* 长度填充来改变元素值
* copyWithin* 长度不变的选区覆盖
* reverse* 序号反转,倒序
* sort* 自定义排列顺序
* toSorted 函数式 sort 方法
*/
test("fill用法", () => {
const arr = [];
arr.length = 3;
arr.fill(0); // 第三个参数不写,默认值为arr.length
expect(arr).toEqual([0, 0, 0]);
arr.length = 6;
arr.fill(1, 3, arr.length); // 第二和第三个参数的用法,范围[index1,index2)
expect(arr).toEqual([0, 0, 0, 1, 1, 1]);
});
test("copyWithin用法", () => {
const arr = [0, 1, 2, 3, 4, 5];
expect(arr.copyWithin(4, 0, 3)).toEqual([0, 1, 2, 3, 0, 1]);
expect(arr.copyWithin(4, 0, 4)).toEqual([0, 1, 2, 3, 0, 1]); // 即使范围右值变化,数组长度不变
});
test("reverse用法", () => {
const arr = [0, 1, 2, 3];
arr.reverse();
expect(arr).toEqual([3, 2, 1, 0]); // 副作用方法
});
test("sort自定义排序。返回值为 false 就调换两者的位置", () => {
// 需求:根据年龄升序排序
const users = [
{ name: "John", age: 30 },
{ name: "Jane", age: 25 },
{ name: "Doe", age: 28 },
];
users.sort((a, b) => a.age - b.age);
expect(users[0].age).not.toBe(30); // 副作用方法
expect(users[0].age).toBe(25);
});
test("toSort,无副作用", () => {
// 需求:根据年龄升序排序
const users = [
{ name: "John", age: 30 },
{ name: "Jane", age: 25 },
{ name: "Doe", age: 28 },
];
const users2 = users.toSorted((a, b) => a.age - b.age);
expect(users[0].age).toBe(30); // 无副作用方法
expect(users2[0].age).toBe(25);
});
66 changes: 66 additions & 0 deletions codes/js/std/Array/other.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* keys 返回iterator 对象
* values 返回 iterator 对象
* flat 数组降维
* flatMap 高级数组降维,外层map里层 flat
* concat 合并数组(单层)
* join 转为字符串
* entries 数据类型转换
* Array.isArray(array) 是否为数组
* Array.of(...elementN) 元素序列转数组
* Array.from(arrayLike, [cb], [thisArg]) 类数组转数组
* Array.fromAsync(arrayLike, [cb], [thisArg]) 同上的异步方法
*/
test("keys&values用法", () => {
const arr = ["a", "b", "c"];
const iterator = arr.values();
let count = 0;
for (const value of iterator) {
expect(value).toBe(arr[count]);
count++;
}
});
test("flat&flatmap用法", () => {
const arr = [1, [2, [3, [4]]]];
arr.length = 5;
// flat会删除稀疏数组的空槽
// flat不处理类数组的元素
expect(arr.flat(Infinity)).toEqual([1, 2, 3, 4]);
// flatmap,即外层是map,里层是深度为 1的flat
const result = arr.flatMap((element, index, array) => element);
expect(result).toEqual([1, 2, [3, [4]]]);
});
test("concat用法", () => {
const arr1 = [1, 2];
const arr2 = [3, 4];
expect(arr1.concat(arr2)).toEqual([1, 2, 3, 4]);
});
test("join用法", () => {
const arr = [1, 2, 3];
expect(arr.join(",")).toBe("1,2,3");
});
test("entries用法", () => {
const arr = ["a", "b", "c"];
const entries = arr.entries();
let count = 0;
for (const entry of entries) {
expect(entry).toEqual([count, arr[count]]);
count++;
}
});
test("isArray用法", () => {
const arr = [];
expect(Array.isArray(arr)).toBeTruthy();
});
test("Array.of用法", () => {
expect(Array.of(1, 2, 3)).toEqual(Array(1, 2, 3)); // [1, 2, 3]
const arr = [];
arr.length = 3;
expect(arr).toEqual(Array(3)); // 两种空槽数组的产生
});
test("Array.from&fromAsync用法", () => {
// 应用于可迭代对象或者类数组对象
// 可迭代对象:部署了object[Symbol.iterator]
// 类数组对象:拥有 length属性 和索引元素的对象
// TODO
});
65 changes: 65 additions & 0 deletions codes/js/std/Array/query.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* ===query===
* ---查位置---
* findIndex/findLastIndex(callbackFn) 匹配的第一个/最后一个索引
* indexOf/lastIndexOf(searchElement, fromIndex) 匹配的第一个/最后一个索引
* ---查元素或集合---
* includes 是否包含元素
* find/findLast((element,index,array)=>{}) 匹配的第一个/最后一个元素值
* at 按位置返回元素
* with 替换一个元素
* slice 范围切片
*/
test("findIndex/findLastIndex用法", () => {
const arr = ["a", "b", "a"];
function callbackFn(element, index, array) {
return element === "a";
}
expect(arr.findIndex(callbackFn)).toBe(0);
expect(arr.findLastIndex(callbackFn)).toBe(2);
});
test("indexOf/lastIndexOf用法", () => {
const arr = ["a", "b", "a"];
expect(arr.indexOf("a")).toBe(0);
expect(arr.lastIndexOf("a")).toBe(2);
});
test("includes用法", () => {
const arr = ["a", "b", "a"];
expect(arr.includes("a")).toBeTruthy();
expect(arr.includes("b")).toBeTruthy();
expect(arr.includes("c")).not.toBeTruthy();
});
test("find/findLast用法", () => {
const arr = ["a", "b", "a"];
let index1 = 0;
let index2 = 0;
arr.find((item, index) => {
index1 = index;
return item === "a";
});
arr.findLast((item, index) => {
index2 = index;
return item === "a";
});
expect([index1, index2]).toEqual([0, 2]);
});
test("at用法,相比属性访问器可以使用负数取值", () => {
const arr = ["a", "b", "c"];
// 第一个元素序号为 0,最后一个元素序号为-1,不对称。
expect(arr.at(0)).toBe("a");
expect(arr.at(2)).toBe("c");
expect(arr.at(-1)).toBe("c");
expect(arr.at(-2)).toBe("b");
});
test("with用法,替换一个元素值,返回密集数组", () => {
const arr = ["a", "b", "c"];
expect(arr.with(0, "x")).toEqual(["x", "b", "c"]);
expect(arr.with(-1, "z")).toEqual(["a", "b", "z"]);
});
test("slice用法,通常用来浅拷贝", () => {
const object = { name: "slice" };
const arr = [object];
const slicedArr = arr.slice(); // 浅拷贝
object.name = "sliced"; // 修改对象
expect(slicedArr[0]).toEqual(arr[0]); // 指针地址相同
});
38 changes: 19 additions & 19 deletions docs/.vitepress/sidebar/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,31 @@ export default {
{ text: "overview", link: "upl/js/structure" },
{
text: "element",
link: "upl/js/structure/element",
// link: "upl/js/structure/element",
},
{
text: "declaration",
link: "upl/js/structure/declaration",
// link: "upl/js/structure/declaration",
},
{
text: "segmentation",
link: "upl/js/structure/segmentation",
// link: "upl/js/structure/segmentation",
},
{
text: "organization",
link: "upl/js/structure/organization",
// link: "upl/js/structure/organization",
},
{
text: "programming ",
link: "upl/js/structure/programming",
// link: "upl/js/structure/programming",
},
{
text: "scope",
link: "upl/js/structure/scope",
// link: "upl/js/structure/scope",
},
{
text: "private",
link: "upl/js/structure/private",
// link: "upl/js/structure/private",
},
],
},
Expand Down Expand Up @@ -107,28 +107,28 @@ export default {
collapsed: true,
items: [
{
text: "Functional 函数式",
text: "Functional",
collapsed: true,
items: [
{
text: "overview 概况",
link: "upl/js/functional/overview/",
text: "overview",
link: "/upl/js/paradigm/fp",
},
{
text: "从运算式语言到函数式语言",
link: "upl/js/functional/arithmeticToFunctional/",
text: "operational",
link: "/upl/js/paradigm/fp/operational",
},
{
text: "function 函数",
link: "upl/js/functional/function/",
text: "function",
link: "/upl/js/paradigm/fp/function",
},
{
text: "functionBehavior 函数行为",
link: "upl/js/functional/functionBehavior/",
text: "函数行为",
link: "/upl/js/paradigm/fp/behavior",
},
{
text: "closure 闭包",
link: "upl/js/functional/closure/",
text: "closure",
link: "/upl/js/paradigm/fp/closure",
},
],
},
Expand Down Expand Up @@ -186,7 +186,7 @@ export default {
],
},
{
text: "Build-in Objects",
text: "Global Objects",
collapsed: true,
items: jsstd,
},
Expand Down
2 changes: 1 addition & 1 deletion docs/.vitepress/sidebar/js-std.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default [
},
{
text: "Keyed-Collections(键值集合)",
collapsed: false,
collapsed: true,
items: [
{
text: "Object",
Expand Down
Loading

0 comments on commit 3fb996b

Please sign in to comment.