json-logic icon indicating copy to clipboard operation
json-logic copied to clipboard

Add a "length" operation.

Open jwadhams opened this issue 6 years ago • 6 comments

For strings, returns their length in characters. (Note there can be oddities in a language's string length calculation, like JavaScript's "🤔 ".length === 2)

For arrays, returns the number of elements.

For non-countables (null, boolean, objects, numbers) returns 0 (zero)

Should internally use the widest idiomatic counting solution in the target language (e.g. the length magic parameter in JavaScript, the count() method and Countable interface in PHP, the len function and __len__ special method in Python, etc.)

Note, this is going to have a really hard relationship with the unary sugar. This could be ambiguous {"length":["apple"]} -- am I counting a one-element-array or a five-letter-word? I think we have to side with "assume the rule author is not using unary syntax." which means arrays have to be written {"length":[ [1,2,3] ]}

jwadhams avatar Jul 28 '17 19:07 jwadhams

Proposed tests, in the common test format from http://jsonlogic.com/tests.json like

[ test, data, expected result ]

"Unary syntax sugar, interpreted as one string arg",
[ {"length":"apple"}, null, 5], 
"Normal syntax, interpreted as one string arg",
[ {"length":["apple"]}, null, 5],
"Interpreted as one argument, an array with one element",
[ {"length":[ ["apple"] ]}, null, 1],

"Interpreted as two string arguments, second is ignored.",
[ {"length":["apple", "banana"]}, null, 5],
"Interpreted as one array argument",
[ {"length":[ ["apple", "banana"] ]}, null, 2],

"Unlengthable",
[ {"length":null}, null, 0],
[ {"length":[null]}, null, 0],
[ {"length":false}, null, 0],
[ {"length":[false]}, null, 0],
[ {"length":true}, null, 0],
[ {"length":[true]}, null, 0],
[ {"length":42}, null, 0],
[ {"length":[42]}, null, 0],
[ {"length":{"var":"a"}}, {"a":{"b":"banana"}}, 0],
[ {"length":[{"var":"a"}]}, {"a":{"b":"banana"}}, 0],

jwadhams avatar Jul 28 '17 19:07 jwadhams

Yes, please 👍

MatissJanis avatar Dec 12 '17 14:12 MatissJanis

Yes, this would be quite useful. In the meantime, one could do this to count elements in an array:

{
    "reduce": [
        {"map": [[1, 2, 3, 4], {"if": [{"var": ""}, 1, 0]}]},
        {"+": [{"var": "current"}, {"var": "accumulator"}]},
        0
    ]
}

ilons avatar Jul 03 '18 08:07 ilons

May i know what is pending for this Pull Request?

atulagrawal avatar Feb 15 '19 07:02 atulagrawal

FYI, the simpler way to get the length of an array would be:

{
    "reduce": [
        [1, 2, 3, 4],
        {"+": [1, {"var": "accumulator"}]},
        0
    ]
}

edene avatar Dec 09 '19 20:12 edene

Are there plans to add this operation?

danielwolf1 avatar Apr 26 '22 12:04 danielwolf1

Has there been any updates to this? I see work-arounds for arrays but we have a use case where we need this for strings. So for example, a string needs to have at least 5 characters ( length >= 5 ).

xStoryTeller avatar Feb 13 '24 11:02 xStoryTeller