diff --git a/packages/amis-formula/__tests__/evalute.test.ts b/packages/amis-formula/__tests__/evalute.test.ts index cc21e8a55..ce59fb678 100644 --- a/packages/amis-formula/__tests__/evalute.test.ts +++ b/packages/amis-formula/__tests__/evalute.test.ts @@ -428,7 +428,22 @@ test('evalute:array:func', () => { id: 1.1, name: 1.3 } - ] + ], + obj1: { + p1: 'name', + p2: 'age', + p3: 'obj', + p4: [ + { + p41: 'Tom', + p42: 'Jerry' + }, + { + p41: 'baidu', + p42: 'amis' + } + ] + } }; expect(evaluate('${COMPACT(arr1)}', data)).toMatchObject([1, 2, 3]); @@ -486,8 +501,13 @@ test('evalute:array:func', () => { expect(evaluate('${ARRAYINCLUDES(arr1, false)}', data)).toBe(true); - expect(evaluate('${ARRAYNTH(arr1, 1)}', data)).toBe(1); - expect(evaluate('${ARRAYNTH(arr1, -4)}', data)).toBe(false); + expect(evaluate('${GET(arr1, 2)}', data)).toBe(false); + expect(evaluate('${GET(arr1, 6, "not-found")}', data)).toBe('not-found'); + expect(evaluate('${GET(arr5, "[2].name")}', data)).toBe(1.3); + expect(evaluate('${GET(arr5, "2.name")}', data)).toBe(1.3); + expect(evaluate('${GET(obj1, "p2")}', data)).toBe('age'); + expect(evaluate('${GET(obj1, "p4.1.p42")}', data)).toBe('amis'); + expect(evaluate('${GET(obj1, "p4[1].p42")}', data)).toBe('amis'); }); test('evalute:ISTYPE', () => { diff --git a/packages/amis-formula/src/doc.md b/packages/amis-formula/src/doc.md index e00a8843b..89870e228 100644 --- a/packages/amis-formula/src/doc.md +++ b/packages/amis-formula/src/doc.md @@ -942,21 +942,6 @@ ARRAYEVERY([0, 2, false], item => item === 2) 得到 false ARRAYINCLUDES([0, 2, false], 2) 得到 true -### ARRAYNTH - -用法:`ARRAYNTH(arr, 2)` - - * `arr:Array` 数组 - * `n:number` 索引 - -返回:`any` 结果 - -获取数据的第n个元素,n为0表示取第一个元素 - -示例: - -ARRAYNTH([0, 2, false], 1) 得到 2 - ### COMPACT 用法:`COMPACT(arr)` @@ -1017,6 +1002,26 @@ UNIQ([{a: '1'}, {b: '2'}, {a: '1'}], 'id') ## 其他 +### GET + +用法:`GET(arr, 2)` + + * `obj:any` 对象或数组 + * `path:string` 路径 + +返回:`any` 结果 + +根据对象或者数组的path路径获取值。 如果解析 value 是 undefined 会以 defaultValue 取代 + +示例: + +GET([0, 2, {name: 'amis', age: 18}], 1) 得到 2 +GET([0, 2, {name: 'amis', age: 18}], '2.name') 得到 'amis' +GET([0, 2, {name: 'amis', age: 18}], '[2].name') 得到 'amis' +GET({arr: [{name: 'amis', age: 18}]}, 'arr[0].name') 得到 'amis' +GET({arr: [{name: 'amis', age: 18}]}, 'arr.0.name') 得到 'amis' +GET({arr: [{name: 'amis', age: 18}]}, 'arr.1.name', 'not-found') 得到 'not-found' + ### ISTYPE 用法:`ISTYPE([{a: '1'}, {b: '2'}, {a: '1'}], 'array')` diff --git a/packages/amis-formula/src/doc.ts b/packages/amis-formula/src/doc.ts index a8d820446..6592fa7a8 100644 --- a/packages/amis-formula/src/doc.ts +++ b/packages/amis-formula/src/doc.ts @@ -1614,26 +1614,26 @@ export const doc: { namespace: "数组" }, { - name: "ARRAYNTH", - description: "获取数据的第n个元素,n为0表示取第一个元素\n\n示例:\n\nARRAYNTH([0, 2, false], 1) 得到 2", - example: "ARRAYNTH(arr, 2)", + name: "GET", + description: "根据对象或者数组的path路径获取值。 如果解析 value 是 undefined 会以 defaultValue 取代\n\n示例:\n\nGET([0, 2, {name: 'amis', age: 18}], 1) 得到 2\nGET([0, 2, {name: 'amis', age: 18}], '2.name') 得到 'amis'\nGET([0, 2, {name: 'amis', age: 18}], '[2].name') 得到 'amis'\nGET({arr: [{name: 'amis', age: 18}]}, 'arr[0].name') 得到 'amis'\nGET({arr: [{name: 'amis', age: 18}]}, 'arr.0.name') 得到 'amis'\nGET({arr: [{name: 'amis', age: 18}]}, 'arr.1.name', 'not-found') 得到 'not-found'", + example: "GET(arr, 2)", params: [ { - type: "Array", - name: "arr", - description: "数组" + type: "any", + name: "obj", + description: "对象或数组" }, { - type: "number", - name: "n", - description: "索引" + type: "string", + name: "path", + description: "路径" } ], returns: { type: "any", description: "结果" }, - namespace: "数组" + namespace: "其他" }, { name: "COMPACT", diff --git a/packages/amis-formula/src/evalutor.ts b/packages/amis-formula/src/evalutor.ts index 05936ca56..a09477848 100644 --- a/packages/amis-formula/src/evalutor.ts +++ b/packages/amis-formula/src/evalutor.ts @@ -12,6 +12,7 @@ import uniqWith from 'lodash/uniqWith'; import uniqBy from 'lodash/uniqBy'; import isEqual from 'lodash/isEqual'; import isPlainObject from 'lodash/isPlainObject'; +import get from 'lodash/get'; import {EvaluatorOptions, FilterContext, FilterMap, FunctionMap} from './types'; export class Evaluator { @@ -1955,21 +1956,25 @@ export class Evaluator { } /** - * 获取数据的第n个元素,n为0表示取第一个元素 + * 根据对象或者数组的path路径获取值。 如果解析 value 是 undefined 会以 defaultValue 取代 * * 示例: * - * ARRAYNTH([0, 2, false], 1) 得到 2 + * GET([0, 2, {name: 'amis', age: 18}], 1) 得到 2 + * GET([0, 2, {name: 'amis', age: 18}], '2.name') 得到 'amis' + * GET([0, 2, {name: 'amis', age: 18}], '[2].name') 得到 'amis' + * GET({arr: [{name: 'amis', age: 18}]}, 'arr[0].name') 得到 'amis' + * GET({arr: [{name: 'amis', age: 18}]}, 'arr.0.name') 得到 'amis' + * GET({arr: [{name: 'amis', age: 18}]}, 'arr.1.name', 'not-found') 得到 'not-found' * - * @param {Array} arr 数组 - * @param {number} n 索引 - * @namespace 数组 - * @example ARRAYNTH(arr, 2) + * @param {any} obj 对象或数组 + * @param {string} path 路径 + * @namespace 其他 + * @example GET(arr, 2) * @returns {any} 结果 */ - fnARRAYNTH(arr: any[], n: number) { - const tempArr = Array.isArray(arr) ? arr : []; - return tempArr.length ? tempArr[n > 0 ? n : tempArr.length + n] : undefined; + fnGET(obj: any, path: string, defaultValue?: any) { + return get(obj, path, defaultValue); } /**