From 678cc6cf72a79e6c71416623a3f6bd0634cd8c11 Mon Sep 17 00:00:00 2001 From: Adi Fatkhurozi Date: Wed, 25 Oct 2023 09:43:11 +0700 Subject: [PATCH] fix: enhance function expression --- src/createParser.ts | 40 ++++++++++++++++++++++++++++++++++++++++ src/test/index.test.ts | 25 +++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/createParser.ts b/src/createParser.ts index 50452e2..92a46b4 100644 --- a/src/createParser.ts +++ b/src/createParser.ts @@ -166,6 +166,46 @@ export function createParser(props: ExpressionParserConstructor = {}) { return filteredItems; }, + unique: (state, items: any[], filterExpression?: string) => { + const filteredItems = items?.reduce( + (uniqueList: any[], item: any, index) => { + if (!filterExpression) { + if (uniqueList.includes(item)) return uniqueList; + return [...uniqueList, item] + } else { + const hasIncluded = uniqueList.some((uniqueItem) => { + const uniqueItemValue = parser.evaluate( + filterExpression, + { + ...state.variables, + _item_: uniqueItem, + _index_: index + } + ) + const currValue = parser.evaluate( + filterExpression, + { + ...state.variables, + _item_: item, + _index_: index + } + ) + return uniqueItemValue === currValue + }) + + if (hasIncluded) { + return uniqueList; + } else { + return [...uniqueList, item] + } + } + }, + [] + ); + + return filteredItems; + + } } parser.setFunctions(functions) diff --git a/src/test/index.test.ts b/src/test/index.test.ts index b2e61f1..26a8a2d 100644 --- a/src/test/index.test.ts +++ b/src/test/index.test.ts @@ -52,12 +52,31 @@ describe('example', () => { }) it('array method', () => { const parser = createParser(); + + expect( + parser.evaluate('unique(products)', { + products: [1, 1, 4, 5, 6, 6, 7, 7, 8, 8] + }) + ).toEqual([1, 4, 5, 6, 7, 8]) + const products = [ { name: 'Product 1', price: 150, quantity: 2 }, { name: 'Product 2', price: 80, quantity: 0 }, { name: 'Product 3', price: 200, quantity: 5 }, + { name: 'Product 4', price: 120, quantity: 1 }, { name: 'Product 4', price: 120, quantity: 1 } ]; + expect( + parser.evaluate('unique(products, "_item_.name")', { + products + }) + ).toEqual([ + { name: 'Product 1', price: 150, quantity: 2 }, + { name: 'Product 2', price: 80, quantity: 0 }, + { name: 'Product 3', price: 200, quantity: 5 }, + { name: 'Product 4', price: 120, quantity: 1 }, + ]) + expect( parser.evaluate('filter(products, "_item_.price > 100 and _item_.quantity > 0")', { products @@ -65,7 +84,8 @@ describe('example', () => { ).toEqual([ { name: 'Product 1', price: 150, quantity: 2 }, { name: 'Product 3', price: 200, quantity: 5 }, - { name: 'Product 4', price: 120, quantity: 1 } + { name: 'Product 4', price: 120, quantity: 1 }, + { name: 'Product 4', price: 120, quantity: 1 }, ]) expect( @@ -77,6 +97,7 @@ describe('example', () => { 'Product 2', 'Product 3', 'Product 4', + 'Product 4', ]) expect( @@ -99,7 +120,7 @@ describe('example', () => { parser.evaluate('reduce(products, "_curr_ + _item_.price", 0)', { products }) - ).toBe(550) + ).toBe(670) }) it('object', () => { const parser = createParser();