Add hasvalue builtin function (#2026)

This commit is contained in:
Balki 2026-04-08 12:33:12 +00:00 committed by GitHub
parent d0dec461ab
commit c88142a9e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 102 additions and 0 deletions

View file

@ -185,6 +185,35 @@ func BIF_haskey(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromNotCollectionError("haskey", input1)
}
func has_value_in_array(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
arrayval := input1.AcquireArrayValue()
for _, element := range arrayval {
if mlrval.Equals(element, input2) {
return mlrval.TRUE
}
}
return mlrval.FALSE
}
func has_value_in_map(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
mapval := input1.AcquireMapValue()
for pe := mapval.Head; pe != nil; pe = pe.Next {
if mlrval.Equals(pe.Value, input2) {
return mlrval.TRUE
}
}
return mlrval.FALSE
}
func BIF_hasvalue(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsArray() {
return has_value_in_array(input1, input2)
} else if input1.IsMap() {
return has_value_in_map(input1, input2)
}
return mlrval.FromNotCollectionError("hasvalue", input1)
}
func BIF_concat(mlrvals []*mlrval.Mlrval) *mlrval.Mlrval {
output := mlrval.FromEmptyArray()

View file

@ -40,6 +40,71 @@ func TestBIF_depth(t *testing.T) {
assert.Equal(t, int64(1), intval)
}
func TestBIF_hasvalue(t *testing.T) {
t.Run("array with existing value", func(t *testing.T) {
arrayval := make([]*mlrval.Mlrval, 3)
arrayval[0] = mlrval.FromInt(1)
arrayval[1] = mlrval.FromInt(2)
arrayval[2] = mlrval.FromInt(3)
input1 := mlrval.FromArray(arrayval)
input2 := mlrval.FromInt(2)
output := BIF_hasvalue(input1, input2)
boolval, ok := output.GetBoolValue()
assert.True(t, ok)
assert.True(t, boolval)
})
t.Run("array without existing value", func(t *testing.T) {
arrayval := make([]*mlrval.Mlrval, 3)
arrayval[0] = mlrval.FromInt(1)
arrayval[1] = mlrval.FromInt(2)
arrayval[2] = mlrval.FromInt(3)
input1 := mlrval.FromArray(arrayval)
input2 := mlrval.FromInt(5)
output := BIF_hasvalue(input1, input2)
boolval, ok := output.GetBoolValue()
assert.True(t, ok)
assert.False(t, boolval)
})
t.Run("map with existing value", func(t *testing.T) {
mapval := mlrval.NewMlrmap()
mapval.PutReference("a", mlrval.FromString("apple"))
mapval.PutReference("b", mlrval.FromString("banana"))
mapval.PutReference("c", mlrval.FromString("cherry"))
input1 := mlrval.FromMap(mapval)
input2 := mlrval.FromString("banana")
output := BIF_hasvalue(input1, input2)
boolval, ok := output.GetBoolValue()
assert.True(t, ok)
assert.True(t, boolval)
})
t.Run("map without existing value", func(t *testing.T) {
mapval := mlrval.NewMlrmap()
mapval.PutReference("a", mlrval.FromString("apple"))
mapval.PutReference("b", mlrval.FromString("banana"))
input1 := mlrval.FromMap(mapval)
input2 := mlrval.FromString("orange")
output := BIF_hasvalue(input1, input2)
boolval, ok := output.GetBoolValue()
assert.True(t, ok)
assert.False(t, boolval)
})
t.Run("not a collection - should error", func(t *testing.T) {
input1 := mlrval.FromInt(123)
input2 := mlrval.FromInt(1)
output := BIF_hasvalue(input1, input2)
assert.False(t, output.IsBool())
})
}
// TODO: copy in more unit-test cases from existing regression-test data
// func leafcount_from_array(input1 *mlrval.Mlrval) *mlrval.Mlrval

View file

@ -2250,6 +2250,14 @@ or true/false if array index is in bounds / out of bounds. Error if 1st argumen
binaryFunc: bifs.BIF_haskey,
},
{
name: "hasvalue",
class: FUNC_CLASS_COLLECTIONS,
help: `True/false if map/array has/hasn't value, e.g. 'hasvalue($*, "a")' or 'hasvalue(myarray, myvalue)',
returns true if the value is present in the collection. Error if 1st argument is not a map or array.`,
binaryFunc: bifs.BIF_hasvalue,
},
{
name: "json_parse",
class: FUNC_CLASS_COLLECTIONS,