From 0e41758bccc6876df9e810f719c9e32eb85e6f79 Mon Sep 17 00:00:00 2001 From: Zhang Eric Date: Tue, 12 May 2020 23:55:11 +0800 Subject: [PATCH] #234 Added code to implement for rel.Array. --- syntax/std_seq.go | 21 ++++----------------- syntax/std_seq_helper.go | 30 ++++++++++++++++++++++++++++-- syntax/std_seq_test.go | 11 ++++++++++- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/syntax/std_seq.go b/syntax/std_seq.go index eff99ba7..00679f5d 100644 --- a/syntax/std_seq.go +++ b/syntax/std_seq.go @@ -98,24 +98,11 @@ var ( typeMethod{reflect.TypeOf(rel.String{}), "contains"}: func(args ...rel.Value) rel.Value { return rel.NewBool(strings.Contains(mustAsString(args[0]), mustAsString(args[1]))) }, - typeMethod{reflect.TypeOf(rel.Array{}), "contains"}: func(args ...rel.Value) rel.Value { - a := args[0].(rel.Array) - switch b := args[1].(type) { - case rel.Array: - return ContainsArray(a, b) - case rel.Value: - arrayEnum, _ := a.ArrayEnumerator() - if arrayEnum != nil { - for arrayEnum.MoveNext() { - if arrayEnum.Current().Equal(b) { - return rel.NewBool(true) - } - } - } - } - return rel.NewBool(false) + typeMethod{reflect.TypeOf(rel.Array{}), "contains"}: func(args ...rel.Value) rel.Value { + return ArrayContains(args[0].(rel.Array), args[1]) }, + typeMethod{reflect.TypeOf(rel.Bytes{}), "contains"}: func(args ...rel.Value) rel.Value { return nil }, @@ -132,7 +119,7 @@ var ( ) }, typeMethod{reflect.TypeOf(rel.Array{}), "sub"}: func(args ...rel.Value) rel.Value { - return nil + return ArraySub(args[0].(rel.Array), args[1], args[2]) }, typeMethod{reflect.TypeOf(rel.Bytes{}), "sub"}: func(args ...rel.Value) rel.Value { return nil diff --git a/syntax/std_seq_helper.go b/syntax/std_seq_helper.go index dd98b21e..8f1c3fba 100644 --- a/syntax/std_seq_helper.go +++ b/syntax/std_seq_helper.go @@ -4,8 +4,25 @@ import ( "github.com/arr-ai/arrai/rel" ) -// ContainsArray check if array a contains array b. -func ContainsArray(a rel.Array, b rel.Array) rel.Value { +// ArrayContains check if array a contains b, and b can be rel.Value or rel.Array. +func ArrayContains(a rel.Array, b rel.Value) rel.Value { + switch b := b.(type) { + case rel.Array: + return arrayContainsArray(a, b) + case rel.Value: + arrayEnum, _ := a.ArrayEnumerator() + if arrayEnum != nil { + for arrayEnum.MoveNext() { + if arrayEnum.Current().Equal(b) { + return rel.NewBool(true) + } + } + } + } + return rel.NewBool(false) +} + +func arrayContainsArray(a, b rel.Array) rel.Value { // Get index of b[0] in a bOffset := 0 bVals := b.Values() @@ -26,3 +43,12 @@ func ContainsArray(a rel.Array, b rel.Array) rel.Value { return rel.NewBool(false) } + +// ArraySub substitutes all b in a with c. +func ArraySub(a rel.Array, b, c rel.Value) rel.Value { + // switch b := b.(type) { + // case rel.Array: + // return arrayContainsArray(a, b) + // case rel.Value: + return nil +} diff --git a/syntax/std_seq_test.go b/syntax/std_seq_test.go index 2a618ecd..7cc7ed4c 100644 --- a/syntax/std_seq_test.go +++ b/syntax/std_seq_test.go @@ -60,11 +60,14 @@ func TestContains(t *testing.T) { AssertCodesEvalToSameValue(t, `false`, `//seq.contains(['A','B','C','D','E'],['B','C','E'])`) AssertCodesEvalToSameValue(t, `false`, `//seq.contains(['A','B','C','D','E'],['A','B','C','E'])`) AssertCodesEvalToSameValue(t, `false`, `//seq.contains(['A','B','C','D','E'],['A','B','C','D','E','F'])`) + // bytes + } /////////////////// -func TestStrSub(t *testing.T) { +func TestSub(t *testing.T) { t.Parallel() + // string AssertCodesEvalToSameValue(t, `"this is a test"`, `//seq.sub("this is not a test", "is not", "is")`) @@ -75,6 +78,12 @@ func TestStrSub(t *testing.T) { `"this is still a test"`, `//seq.sub("this is still a test", "doesn't matter", "hello there")`) assertExprPanics(t, `//seq.sub("hello there", "test", 1)`) + // array + // AssertCodesEvalToSameValue(t, + // `"this is a test"`, + // `//seq.sub(["this", "is", "not", "a", "test"], ["is", "not"], "is")`) + // bytes + } func TestStrSplit(t *testing.T) {