判断数组中是否包含某个元素

663 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

判断数组中是否包含某个元素

Java 中要判断某个数组是否包含某个元素

一般有如下方式:

arr 转为 list,然后使用 contains 判断

  String[] strArr = new String[] { "a", "b", "c"};
  String str = "c";
  List<String> list = Arrays.asList(strArr);
  boolean result = list.contains(str);
  System.out.println(result); // true

使用循环判断

String[] strArr = new String[] { "a", "b", "c" };
    String str = "c";
    for (int i = 0; i < strArr.length; i++) {
        if (strArr[i].equals(str)) {
            System.out.println("该元素在数组中: i=" + i); // 该元素在数组中: i=2
        }
    }

使用 Apache Commons类库

String[] strArr = new String[] { "a", "b", "c" };
String str = "c";
boolean result = ArrayUtils.contains(strArr, str); // 推荐
System.out.println(result); // true

Go 中判断数组是否包含某个元素

循环实现

最常见的办法,对数组进行遍历,一个个比对,看是否能找到那个元素,找到了就返回 true 没找到返回false

func StringsContains(array []string, val string) bool {
	for i := 0; i < len(array); i++ {
		if array[i] == val {
			return true
		}
	}
	return false
}

使用反射进行实现

这个思路其实还行循环,但是可以比对任意类型的数据,判断元素是否在数组中。

func TestArrContainsItem(t *testing.T) {
	arr := []string{"hello", "world"}
	item := "hello"
	item1 := "test"
	assert.Equal(t, IsContains(arr, item), true)
	assert.Equal(t, IsContains(arr, item1), false)

}

func IsContains(array interface{}, val interface{}) bool {
	switch reflect.TypeOf(array).Kind() {
	case reflect.Slice:
		{
			s := reflect.ValueOf(array)
			for i := 0; i < s.Len(); i++ {
				if reflect.DeepEqual(val, s.Index(i).Interface()) {
					return true
				}
			}
		}
	}
	return false
}

bench mark test

func BenchmarkContains(b *testing.B) {
	sa := []string{"q", "w", "e", "r", "t"}
	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		IsContains(sa, "r")
	}
}

func BenchmarkStringsContains(b *testing.B) {
	sa := []string{"q", "w", "e", "r", "t"}
	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		StringsContains(sa, "r")
	}
}

执行 Benchmark

go test -bench=.

执行结果:

➜  array git:(master) ✗ go test -bench=.
[[001 002 003] [11 22]]
[001 002 003]
002
goos: darwin
goarch: amd64
pkg: /GoProject/main/gobase/array
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkContains-12             3003925               402.8 ns/op
BenchmarkStringsContains-12     93780720                13.45 ns/op
PASS
ok      

其实可以很明显的看到 StringsContains 方法平均每次 13.45ns,IsContains 每次 402ns 。 反射这个性能不好。 反射耗时长到原因可能如下:

  • 内存分配导致 GC 问题
  • reflect 使用了switch 中使用了各种枚举

使用其他包 三方包 wgo

 go get -u github.com/wxnacy/wgo
import "github.com/wxnacy/wgo/arrays"

方法包含如下:

// Contains Returns the index position of the val in array
func Contains(array interface{}, val interface{}) (index int)
 
// ContainsString Returns the index position of the string val in array
func ContainsString(array []string, val string) (index int)
 
// ContainsInt Returns the index position of the int64 val in array
func ContainsInt(array []int64, val int64) (index int)
 
// ContainsFloat Returns the index position of the float64 val in array
func ContainsFloat(array []float64, val float64) (index int)
 
// ContainsBool Returns the index position of the bool val in array
func ContainsBool(array []bool, val bool) (index int)

测试代码如下:

import(
	"github.com/stretchr/testify/assert"
	"github.com/wxnacy/wgo/arrays"
)

func TestArrContains_1(t *testing.T) {
	var arr = []int64{1, 3, 4, 8, 12, 4, 9}
	var i int
	i = arrays.ContainsInt(arr, 8)
	fmt.Println(i) // 3
	assert.Equal(t, i, 3)

	i = arrays.Contains(arr, int64(12))
	fmt.Println(i)
	assert.Equal(t, i, 4)
}

执行结果:

=== RUN   TestArrContains_1
3
4
--- PASS: TestArrContains_1 (0.00s)
PASS