From 14d63b7256ec5155f59ac46f5bd00a7a7d4e6b09 Mon Sep 17 00:00:00 2001 From: hjy <1441211576@qq.com> Date: Sun, 12 Jan 2025 20:55:09 +0800 Subject: [PATCH] feat: add new array method:swap|shift|unshift --- apps/web/docs/en/api/data-structure/array.mdx | 29 ++++ apps/web/docs/zh/api/data-structure/array.mdx | 31 ++++ apps/web/src/gallery/contanst.ts | 15 +- .../data-structure/src/alvis/array/array.ts | 42 ++++- .../src/alvis/array/function.ts | 153 ++++++++++-------- .../data-structure/src/alvis/array/index.ts | 35 ++-- packages/data-structure/src/alvis/util.ts | 15 ++ packages/data-structure/src/utils/strategy.ts | 4 +- packages/editor/src/constant.ts | 4 + packages/editor/src/index.tsx | 7 +- packages/exec/src/generateAction.ts | 103 ++++++------ 11 files changed, 279 insertions(+), 159 deletions(-) create mode 100644 packages/data-structure/src/alvis/util.ts create mode 100644 packages/editor/src/constant.ts diff --git a/apps/web/docs/en/api/data-structure/array.mdx b/apps/web/docs/en/api/data-structure/array.mdx index 5ac583a..078958a 100644 --- a/apps/web/docs/en/api/data-structure/array.mdx +++ b/apps/web/docs/en/api/data-structure/array.mdx @@ -64,3 +64,32 @@ Delete any element in the array. ## 6. length Return the length of array. + +## 7. swap(param1, param2) + +Swap two elements in an array. + +**Required parameters** + +`param1|param2`:Parameter 1 & 2, only supports array subscript | current element object. + +**eg**: `arr.swap({ month: 'Tuesday', sales: 13 },{ month: 'Wednesday', sales: 25 })`. + +## 8. shift + +Pop the first element of an array, no parameters. + +## 9. unshift(params) + +Add data to the head of the queue. + +**Required parameters 1** + +`value`: value +**eg**: `arr.unshift(1)` + +**Required parameters 2** + +`object`:new add object + +**eg**: `arr.unshift({ month: 'Monday1', sales: 55 })`, where month is category and sales is value. diff --git a/apps/web/docs/zh/api/data-structure/array.mdx b/apps/web/docs/zh/api/data-structure/array.mdx index 593bced..a8ee51d 100644 --- a/apps/web/docs/zh/api/data-structure/array.mdx +++ b/apps/web/docs/zh/api/data-structure/array.mdx @@ -64,3 +64,34 @@ ## 6. length 返回数组长度,无参数。 + +## 7. swap(param1, param2) + +交换数组中的两个元素 + +**必选参数** + +`param1| param2`:参数 1,仅支持数组下标|当前元素对象。 + +**实例**: `arr.swap({ month: 'Tuesday', sales: 13 },{ month: 'Wednesday', sales: 25 })`. + +## 8. shift + +弹出数组的第一个元素,无参数。 + +## 9. unshift(params) + +队头增加数据。 + +**必选参数 1** + +`value`:数值 +**实例**: `arr.unshift(1)` + +**必选参数 2** + +`category`:类别,如 x 轴标签或类别标签 + +`value`: 值,如 y 轴标签或值标签 + +**实例**: `arr.unshift({ month: 'Monday1', sales: 55 })`,其中 month 为 category,sales 为 value. diff --git a/apps/web/src/gallery/contanst.ts b/apps/web/src/gallery/contanst.ts index 506af3f..81c7286 100644 --- a/apps/web/src/gallery/contanst.ts +++ b/apps/web/src/gallery/contanst.ts @@ -1,8 +1,8 @@ /* * @Author: hh 1441211576@qq.com * @Date: 2024-08-09 11:03:31 - * @LastEditors: hh 1441211576@qq.com - * @LastEditTime: 2024-08-09 15:23:56 + * @LastEditors: hjy 1441211576@qq.com + * @LastEditTime: 2025-01-12 20:18:42 * @FilePath: \algorithm-visualization\apps\website\src\gallery\contanst.ts * @Description: * @@ -15,16 +15,14 @@ const bruteForce = [ for (let i = 0; i < n - 1; i++) { for (let j = 0; j < n - 1 - i; j++) { if (arr[j] > arr[j + 1]) { - // 交换元素 - let temp = arr[j]; - arr[j] = arr[j + 1]; - arr[j + 1] = temp; + // swap + arr.swap(j, j + 1) } } } return arr } - + return defaultFunctionTemplate` ] const dp = [ @@ -69,7 +67,8 @@ const divideConquer = [ } return defaultFunctionTemplate`, - `const defaultFunctionTemplate = function () { + `// quickSort +const defaultFunctionTemplate = function () { const nums = new AlVisArray([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]) qSort(nums, 0, nums.length - 1) return nums; diff --git a/packages/data-structure/src/alvis/array/array.ts b/packages/data-structure/src/alvis/array/array.ts index c0b4700..0f72f92 100644 --- a/packages/data-structure/src/alvis/array/array.ts +++ b/packages/data-structure/src/alvis/array/array.ts @@ -2,7 +2,7 @@ * @Author: hjy 1441211576@qq.com * @Date: 2024-07-01 14:22:28 * @LastEditors: hjy 1441211576@qq.com - * @LastEditTime: 2024-08-10 10:17:19 + * @LastEditTime: 2025-01-12 20:40:24 * @FilePath: \algorithm-visualization\packages\data-structure\src\alvis\array\array.ts * @Description: This is the monoarray */ @@ -14,6 +14,8 @@ import { getFields } from '../../utils/fileds.ts' import { schemaBuilder } from '@alvis/schema/src/builder/schemaBuilder.ts' import { dataStructureInitPropsMap } from '../init/initMap.ts' import { handleInitData } from './initData.ts' +import { findEqualObject } from '../util.ts' + export class AlVisArray { [key: string]: any constructor(dataStructureType: string, config: IInitConfigurationProps) { @@ -61,23 +63,25 @@ export class AlVisArray { getProxy() { const that = this - // debugger + return new Proxy(this, { get(target, property: string) { - // 如果属性是索引,代理数组元素的访问 + // if the property is index, get the element + if (!isNaN(Number(property))) { return target.get(property) } - // 如果属性是类的方法或属性,返回其值 + // if the property is method or attribute, return its value const value = target?.[property] if (typeof value === 'function') { - // 返回方法的绑定版本,使其可以在代理上调用 + // value bind this, to call this func in the proxy return value.bind(that) } return value }, - set(target, property: string, value) { + set(target, property: string, value, receiver: any) { + debugger if (!isNaN(Number(property))) { // 代理数组元素的设置 target.set(+property, value) @@ -96,10 +100,36 @@ export class AlVisArray { this.schema.actions.push({ op: 'push', value: pushData }) } + unshift(unshiftParams: object | number) { + const unshiftData = checkValue(unshiftParams, this.data.length) + this.data.push(unshiftData) + this.schema.actions.push({ op: 'push', value: unshiftData }) + } + pop() { this.data.pop() this.schema.actions.push({ op: 'pop' }) } + shift() { + this.data.shift() + this.schema.actions.push({ op: 'shift' }) + } + + swap(param1: number, param2: number) + swap(param1: object, param2: object) + swap(param1, param2) { + if (typeof param1 === 'number' && typeof param1 === typeof param2) { + ;[this.data[param1], this.data[param2]] = [this.data[param2], this.data[param1]] + } else if (typeof param1 === 'object' && typeof param1 === typeof param2) { + const index1 = findEqualObject(this.data, param1) + const index2 = findEqualObject(this.data, param2) + ;[this.data[index1], this.data[index2]] = [this.data[index2], this.data[index1]] + } else { + alert('swap function incorrectly called') + return + } + this.schema.actions.push({ op: 'swap', value: _.cloneDeep(this.data) }) + } set(params: object | number, value: string) { const category = getFields(this.schema, 'category') diff --git a/packages/data-structure/src/alvis/array/function.ts b/packages/data-structure/src/alvis/array/function.ts index 86d7570..cf82c28 100644 --- a/packages/data-structure/src/alvis/array/function.ts +++ b/packages/data-structure/src/alvis/array/function.ts @@ -1,70 +1,83 @@ -import { arrayOPMap } from '.' -import { OperationParams } from '../../utils/strategy' - -/* - * @Author: hh 1441211576@qq.com - * @Date: 2024-07-11 20:35:09 - * @LastEditors: hh 1441211576@qq.com - * @LastEditTime: 2024-08-05 19:12:58 - * @FilePath: \algorithm-visualization\packages\data-structure\src\alvis\array\function.ts - * @Description: - * - */ -import _ from 'lodash' - -const arrayOperations: arrayOPMap = { - push: (props: OperationParams): Object[] => { - const { data, modifyValue = {} } = props - data.push(modifyValue) - return data - }, - pop: (props: OperationParams) => { - const { data } = props - data.pop() - return data - }, - set: (props: OperationParams): object[] => { - const { data, modifyValue = {}, category = 'key' } = props - let index: number = -1 - data.map((d: object, i) => { - if ( - (d as { [key: string]: object })[category] === - (modifyValue as { [key: string]: object })?.[category] - ) { - index = i - return - } - }) - - if (index < 0) { - const { key, value } = modifyValue as { [key: string]: number } - data[key] = { - id: `${value}-${key}`, - key: key, - value: value - } - } else { - data[index] = modifyValue - } - - return data - }, - insert: (props: OperationParams): Object[] => { - const { data, modifyValue = {}, place = 0 } = props - data.splice(place, 0, modifyValue) - return data - }, - delete: (props: OperationParams): Object[] => { - const { data, modifyValue = {} } = props - const type = Object.keys(modifyValue)[0] - let index = 0 - - data.map((obj, i) => { - if ((obj as { [key: string]: object })[type] === Object.values(modifyValue)[0]) index = i - }) - data.splice(index, 1) - return data - } -} - -export { arrayOperations } +import { arrayOPMap } from '.' +import { OperationParams } from '../../utils/strategy' + +/* + * @Author: hh 1441211576@qq.com + * @Date: 2024-07-11 20:35:09 + * @LastEditors: hjy 1441211576@qq.com + * @LastEditTime: 2025-01-12 20:39:14 + * @FilePath: \algorithm-visualization\packages\data-structure\src\alvis\array\function.ts + * @Description: + * + */ +import _ from 'lodash' + +const arrayOperations: arrayOPMap = { + push: (props: OperationParams): Object[] => { + const { data, modifyValue = {} } = props + data.push(modifyValue) + return data + }, + pop: (props: OperationParams) => { + const { data } = props + data.pop() + return data + }, + set: (props: OperationParams): object[] => { + const { data, modifyValue = {}, category = 'key' } = props + let index: number = -1 + data.map((d: object, i) => { + if ( + (d as { [key: string]: object })[category] === + (modifyValue as { [key: string]: object })?.[category] + ) { + index = i + return + } + }) + + if (index < 0) { + const { key, value } = modifyValue as { [key: string]: number } + data[key] = { + id: `${value}-${key}`, + key: key, + value: value + } + } else { + data[index] = modifyValue + } + + return data + }, + insert: (props: OperationParams): Object[] => { + const { data, modifyValue = {}, place = 0 } = props + data.splice(place, 0, modifyValue) + return data + }, + delete: (props: OperationParams): Object[] => { + const { data, modifyValue = {} } = props + const type = Object.keys(modifyValue)[0] + let index = 0 + + data.map((obj, i) => { + if ((obj as { [key: string]: object })[type] === Object.values(modifyValue)[0]) index = i + }) + data.splice(index, 1) + return data + }, + swap: (props: OperationParams): Object[] => { + return props?.modifyValue as Object[] + }, + shift: (props: OperationParams): Object[] => { + const { data } = props + data.shift() + return data + }, + unshift: (props: OperationParams): Object[] => { + const { data, modifyValue = {} } = props + data.unshift(modifyValue) + return data + } +} + +export { arrayOperations } diff --git a/packages/data-structure/src/alvis/array/index.ts b/packages/data-structure/src/alvis/array/index.ts index 1d62ca6..fff8a53 100644 --- a/packages/data-structure/src/alvis/array/index.ts +++ b/packages/data-structure/src/alvis/array/index.ts @@ -1,17 +1,18 @@ -/* - * @Author: hh 1441211576@qq.com - * @Date: 2024-07-11 20:35:28 - * @LastEditors: hh 1441211576@qq.com - * @LastEditTime: 2024-08-05 19:13:11 - * @FilePath: \algorithm-visualization\packages\data-structure\src\alvis\array\index.ts - * @Description: - * - */ - -export type arrayOP = 'push' | 'pop' | 'set' | 'insert' | 'delete' //| 'length' | 'shift' | 'unshift' | 'swap' - -export type arrayOPMap = Record - -import { AlVisArray } from './array' -import { arrayOperations } from './function' -export { AlVisArray, arrayOperations } +/* + * @Author: hh 1441211576@qq.com + * @Date: 2024-07-11 20:35:28 + * @LastEditors: hjy 1441211576@qq.com + * @LastEditTime: 2025-01-12 20:16:35 + * @FilePath: \algorithm-visualization\packages\data-structure\src\alvis\array\index.ts + * @Description: + * + */ + +// This describes the opereation will infulence the chart. +export type arrayOP = 'push' | 'pop' | 'set' | 'insert' | 'delete' | 'swap' | 'shift' | 'unshift' + +export type arrayOPMap = Record + +import { AlVisArray } from './array' +import { arrayOperations } from './function' +export { AlVisArray, arrayOperations } diff --git a/packages/data-structure/src/alvis/util.ts b/packages/data-structure/src/alvis/util.ts new file mode 100644 index 0000000..7d3a490 --- /dev/null +++ b/packages/data-structure/src/alvis/util.ts @@ -0,0 +1,15 @@ +import _ from 'lodash' + +/* + * @Author: hjy 1441211576@qq.com + * @Date: 2025-01-12 19:37:37 + * @LastEditors: hjy 1441211576@qq.com + * @LastEditTime: 2025-01-12 19:45:26 + * @FilePath: /algorithm-visualization/packages/data-structure/src/alvis/util.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +const findEqualObject = (data: object[], target: object): number => { + return data?.findIndex((item: object, index: number) => _.isEqual(item, target)) +} + +export { findEqualObject } diff --git a/packages/data-structure/src/utils/strategy.ts b/packages/data-structure/src/utils/strategy.ts index d162757..8635a19 100644 --- a/packages/data-structure/src/utils/strategy.ts +++ b/packages/data-structure/src/utils/strategy.ts @@ -1,8 +1,8 @@ /* * @Author: hjy 1441211576@qq.com * @Date: 2024-06-01 16:37:58 - * @LastEditors: hh 1441211576@qq.com - * @LastEditTime: 2024-07-23 21:29:25 + * @LastEditors: hjy 1441211576@qq.com + * @LastEditTime: 2025-01-12 20:08:00 * @FilePath: \algorithm-visualization\packages\data-structure\src\utils\strategy.ts * @Description: this is the operation strategy file.We will define all the operations here. */ diff --git a/packages/editor/src/constant.ts b/packages/editor/src/constant.ts new file mode 100644 index 0000000..bdbe2ea --- /dev/null +++ b/packages/editor/src/constant.ts @@ -0,0 +1,4 @@ +const arrayMethods = ['push', 'pop', 'insert', 'get', 'set', 'delete', 'swap', 'shift', 'unshift'] +const stackMethods = ['push', 'pop'] + +export { arrayMethods, stackMethods } diff --git a/packages/editor/src/index.tsx b/packages/editor/src/index.tsx index 1eeebfc..33d5336 100644 --- a/packages/editor/src/index.tsx +++ b/packages/editor/src/index.tsx @@ -2,7 +2,7 @@ * @Author: hh 1441211576@qq.com * @Date: 2024-06-25 14:56:42 * @LastEditors: hjy 1441211576@qq.com - * @LastEditTime: 2024-11-13 22:18:00 + * @LastEditTime: 2025-01-12 20:14:11 * @FilePath: \algorithm-visualization\packages\editor\src\index.tsx * @Description: * @@ -13,7 +13,7 @@ import { Space, Button, Tooltip } from '@arco-design/web-react' import { IconPlayArrow } from '@arco-design/web-react/icon' import * as monaco from 'monaco-editor' import { useThemeStore } from '@alvis/web/src/store/create' - +import { arrayMethods, stackMethods } from './constant' const MonacoEditor: React.FC<{ onChange: (code: string) => void; code: string }> = ({ onChange, code @@ -62,8 +62,7 @@ const MonacoEditor: React.FC<{ onChange: (code: string) => void; code: string }> } ] const str = model.getValue() - const arrayMethods = ['push', 'pop', 'insert', 'get', 'set', 'delete'] - const stackMethods = ['push', 'pop'] + if (str.includes('AlVisArray') || str.includes('AlVis')) { arrayMethods?.map(d => { suggestions.push({ diff --git a/packages/exec/src/generateAction.ts b/packages/exec/src/generateAction.ts index db4cc2d..372c6cd 100644 --- a/packages/exec/src/generateAction.ts +++ b/packages/exec/src/generateAction.ts @@ -1,52 +1,51 @@ -import { ISchemaProps } from '@alvis/schema/src' -import VChart, { ISpec } from '@visactor/vchart' - -import { ActionExec } from './index' -import { OperationParams } from '@alvis/data-structure/src/utils/strategy' -import { IActions } from './types' -import { arrayOperations } from '@alvis/data-structure/src' -import { IChartProps } from '@alvis/charts/index' -import { arrayOP } from '@alvis/data-structure/src' - -/* - * @Author: hh 1441211576@qq.com - * @Date: 2024-07-11 16:12:57 - * @LastEditors: hh 1441211576@qq.com - * @LastEditTime: 2024-08-05 19:13:59 - * @FilePath: \algorithm-visualization\packages\exec\src\generateAction.ts - * @Description: - * - */ -import _ from 'lodash' -export const actionExec = (action: IActions, spec: IChartProps, schema: ISchemaProps) => { - const { data } = spec - const { category, value } = schema?.fields ?? {} - const actionValue = action?.value - const op: arrayOP = action?.op as arrayOP - const place = action?.place - - const props: OperationParams = { - data: data[0].values as object[], - modifyValue: actionValue, - category: category, - place: place, - value: value - } - // console.log(props) - - data[0].values = _.cloneDeep(arrayOperations[op](props)) - - return spec as ISpec -} - -export const getActionExe = (schema: ISchemaProps): IActions[] => { - return schema.actions -} - -export const getActions = (schema: ISchemaProps, spec: IChartProps, vchart: VChart) => { - const actions = getActionExe(schema) - - const actionExecutor = new ActionExec(spec, vchart, actions, schema) - - return actionExecutor -} +import { ISchemaProps } from '@alvis/schema/src' +import VChart, { ISpec } from '@visactor/vchart' + +import { ActionExec } from './index' +import { OperationParams } from '@alvis/data-structure/src/utils/strategy' +import { IActions } from './types' +import { arrayOperations } from '@alvis/data-structure/src' +import { IChartProps } from '@alvis/charts/index' +import { arrayOP } from '@alvis/data-structure/src' + +/* + * @Author: hh 1441211576@qq.com + * @Date: 2024-07-11 16:12:57 + * @LastEditors: hjy 1441211576@qq.com + * @LastEditTime: 2025-01-12 20:11:35 + * @FilePath: \algorithm-visualization\packages\exec\src\generateAction.ts + * @Description: + * + */ +import _ from 'lodash' +export const actionExec = (action: IActions, spec: IChartProps, schema: ISchemaProps) => { + const { data } = spec + const { category, value } = schema?.fields ?? {} + const actionValue = action?.value + const op: arrayOP = action?.op as arrayOP + const place = action?.place + + const props: OperationParams = { + data: data[0].values as object[], + modifyValue: actionValue, + category: category, + place: place, + value: value + } + + data[0].values = _.cloneDeep(arrayOperations[op](props)) + + return spec as ISpec +} + +export const getActionExe = (schema: ISchemaProps): IActions[] => { + return schema.actions +} + +export const getActions = (schema: ISchemaProps, spec: IChartProps, vchart: VChart) => { + const actions = getActionExe(schema) + + const actionExecutor = new ActionExec(spec, vchart, actions, schema) + + return actionExecutor +}