mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-16 21:00:40 -07:00
feat: Array sum filter (#661)
* feat(filters): add array sum filter * docs(filters): array sum filter * docs: update versoin number in source/filters/sum.md --------- Co-authored-by: Jun Yang <[email protected]>
This commit is contained in:
co-authored by
Jun Yang
parent
fe978c8cd9
commit
629d958b86
@@ -70,6 +70,7 @@ filters:
|
|||||||
strip: strip.html
|
strip: strip.html
|
||||||
strip_html: strip_html.html
|
strip_html: strip_html.html
|
||||||
strip_newlines: strip_newlines.html
|
strip_newlines: strip_newlines.html
|
||||||
|
sum: sum.html
|
||||||
times: times.html
|
times: times.html
|
||||||
truncate: truncate.html
|
truncate: truncate.html
|
||||||
truncatewords: truncatewords.html
|
truncatewords: truncatewords.html
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
title: sum
|
||||||
|
---
|
||||||
|
|
||||||
|
{% since %}v10.10.0{% endsince %}
|
||||||
|
|
||||||
|
Computes the sum of all the numbers in an array.
|
||||||
|
An optional argument specifies which property of the array's items to sum up.
|
||||||
|
|
||||||
|
In this example, assume the object `cart.products` contains an array of all products in the cart of a website.
|
||||||
|
Assume each cart product has a `qty` property that gives the count of that product instance in the cart.
|
||||||
|
Using the `sum` filter we can calculate the total number of products in the cart.
|
||||||
|
|
||||||
|
Input
|
||||||
|
```liquid
|
||||||
|
The cart has {{ order.products | sum: "qty" }} products.
|
||||||
|
```
|
||||||
|
|
||||||
|
Output
|
||||||
|
```text
|
||||||
|
The cart has 7 products.
|
||||||
|
```
|
||||||
@@ -43,6 +43,15 @@ export function * map (this: FilterImpl, arr: Scope[], property: string): Iterab
|
|||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function * sum (this: FilterImpl, arr: Scope[], property?: string): IterableIterator<unknown> {
|
||||||
|
let sum = 0
|
||||||
|
for (const item of toArray(toValue(arr))) {
|
||||||
|
const data = Number(property ? yield this.context._getFromScope(item, stringify(property), false) : item)
|
||||||
|
sum += Number.isNaN(data) ? 0 : data
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
export function compact<T> (this: FilterImpl, arr: T[]) {
|
export function compact<T> (this: FilterImpl, arr: T[]) {
|
||||||
arr = toValue(arr)
|
arr = toValue(arr)
|
||||||
return toArray(arr).filter(x => !isNil(toValue(x)))
|
return toArray(arr).filter(x => !isNil(toValue(x)))
|
||||||
|
|||||||
@@ -74,6 +74,44 @@ describe('filters/array', function () {
|
|||||||
return test(tpl, { arr: [a, b, c] }, 'Alice Bob Carol')
|
return test(tpl, { arr: [a, b, c] }, 'Alice Bob Carol')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
describe('sum', () => {
|
||||||
|
it('should support sum with no args', function () {
|
||||||
|
const ages = [21, null, -4, '4.5', 13.25, undefined, 0]
|
||||||
|
return test('{{ages | sum}}', { ages }, '34.75')
|
||||||
|
})
|
||||||
|
it('should support sum with property', function () {
|
||||||
|
const ages = [21, null, -4, '4.5', 13.25, undefined, 0].map(x => ({ age: x }))
|
||||||
|
return test('{{ages | sum: "age"}}', { ages }, '34.75')
|
||||||
|
})
|
||||||
|
it('should support sum with nested property', function () {
|
||||||
|
const ages = [21, null, -4, '4.5', 13.25, undefined, 0].map(x => ({ age: { first: x } }))
|
||||||
|
return test('{{ages | sum: "age.first"}}', { ages }, '34.75')
|
||||||
|
})
|
||||||
|
it('should support non-array input', function () {
|
||||||
|
const age = 21.5
|
||||||
|
return test('{{age | sum}}', { age }, '21.5')
|
||||||
|
})
|
||||||
|
it('should coerce missing property to zero', function () {
|
||||||
|
const ages = [{ qty: 1 }, { qty: 2, cnt: 3 }, { cnt: 4 }]
|
||||||
|
return test('{{ages | sum}} {{ages | sum: "cnt"}} {{ages | sum: "other"}}', { ages }, '0 7 0')
|
||||||
|
})
|
||||||
|
it('should coerce indexable non-map values to zero', function () {
|
||||||
|
const input = [1, 'foo', { quantity: 3 }]
|
||||||
|
return test('{{input | sum}}', { input }, '1')
|
||||||
|
})
|
||||||
|
it('should coerce unindexable values to zero', function () {
|
||||||
|
const input = [1, null, { quantity: 2 }]
|
||||||
|
return test('{{input | sum}}', { input }, '1')
|
||||||
|
})
|
||||||
|
it('should coerce true to 1', function () {
|
||||||
|
const input = [1, true, null, { quantity: 2 }]
|
||||||
|
return test('{{input | sum}}', { input }, '2')
|
||||||
|
})
|
||||||
|
it('should not support nested arrays', function () {
|
||||||
|
const ages = [1, [2, [3, 4]]]
|
||||||
|
return test('{{ages | sum}}', { ages }, '1')
|
||||||
|
})
|
||||||
|
})
|
||||||
describe('compact', () => {
|
describe('compact', () => {
|
||||||
it('should compact array', function () {
|
it('should compact array', function () {
|
||||||
const posts = [{ category: 'foo' }, { category: 'bar' }, { foo: 'bar' }]
|
const posts = [{ category: 'foo' }, { category: 'bar' }, { foo: 'bar' }]
|
||||||
|
|||||||
Reference in New Issue
Block a user