猿问

如何从一组数组中过滤一个数组,其中一个数组中的所有项都与另一个数组中的某些项匹配?

如何根据字符串数组过滤数组数组?


如果数组中的部分或全部项目存在于另一个数组中,是否有一个some或any等效的 JS/Py 在哪里我可以过滤数组数组?


因此,例如,将其视为源数组:


arrays := [][]string{

        {"some", "value"},

        {"some", "value", "another"},

        {"value", "another", "test"},

        {"value", "test"},

        {"some", "test"},

    }

如果在数组中找到这里的所有项目arrays,我想过滤。[]string{"some", "value"}


预期的输出是


[[some value] [some value another]]

或者,如果我将过滤器更改为[]string{"some", "test"},则预期值为[[some test]]


我可以在我的测试代码中完全正确地理解逻辑


package main


import "fmt"


func inArray(s string, arr []string) bool {

    for _, a := range arr {

        if s == a {

            return true

        }

    }

    return false

}


func main() {

    arrays := [][]string{

        {"some", "value"},

        {"some", "value", "another"},

        {"value", "another", "test"},

        {"value", "test"},

        {"some", "test"},

    }

    filterBy := []string{"some", "value"}

    hold := make([][]string, 0)

    // Ignore this because it doesnt work as expected

    for _, arr := range arrays {

        for _, f := range filterBy {

            if ok := inArray(f, arr); ok {

                hold = append(hold, arr)

            }

        }

    }

    fmt.Println(hold)

}


慕虎7371278
浏览 176回答 3
3回答

慕仙森

检查在每个数组中找到的所有过滤器字符串,然后决定追加到切片中。我还添加了一些评论。 hold := make([][]string, 0) for _, arr := range arrays {    isValid := true // Initialy set true    for _, f := range filterBy {        if ok := inArray(f, arr); !ok {            isValid = false // if any filter string does match then make false and break            break        }    }    // If all filter string found the isValid is true, then append in slice    if(isValid){        hold = append(hold, arr)    }}去游乐场的完整代码在这里但有效的解决方案是filterByMap := make(map[string]bool)// Create a map for filter slicefor _, a := range filterBy {    filterByMap[a] = true}for _, arr := range arrays {    cnt := 0 // Initial the counter    for _, a := range arr {      if filterByMap[a] {          cnt++  // Increment the counter if filter string found      }    }    // Check if all filter string found ? Append if yes    if(cnt >= len(filterBy)){          hold = append(hold, arr)    }}

汪汪一只猫

函数中的逻辑inArray对于检查单针s string是否在大海捞针中是正确的arr []string。如果您想扩展它以检查所有针ss []string是否都存在于大海捞针arr []string中,那么您至少还需要在针上循环。这是一个例子:func allInArray(ss []string, arr []string) bool {    for _, s := range ss {        if !inArray(s, arr) {            return false        }    }    return true}当然,这是非常低效的,因为它在 haystack 上循环的arr次数与ss. 为了提高效率,您可以对 haystack 进行预处理,将其变成 a map[string]struct{},然后根据地图的键检查针头,如下所示:func allInArray(ss []string, arr []string) bool {    present := make(map[string]struct{})    for _, a := range arr {        present[a] = struct{}{}    }    for _, s := range ss {        if _, ok := present[s]; !ok {            return false        }    }    return true}这会迭代arr一次以创建查找映射,然后迭代ss一次,利用映射的恒定查找时间来检查 的元素ss是否存在于arr.

萧十郎

您可以使用我创建的支持 Some() 和 Every() 的https://github.com/ledongthuc/goterators来重用聚合和转换函数。但是对于您的情况,我认为您需要将同一个库与 Filter() 和 Exist() 结合使用。package mainimport (    "fmt"    "github.com/ledongthuc/goterators")func main() {    arrays := [][]string{        {"some", "value"},        {"some", "value", "another"},        {"value", "another", "test"},        {"value", "test"},        {"some", "test"},    }    expected := []string{"some", "value"}    filteredItems := goterators.Filter(arrays, func(itemList []string) bool {        for _, expectedItem := range expected {            if !goterators.Exist(itemList, expectedItem) {                return false            }        }        return true    })    fmt.Println(filteredItems)}此库需要 Go 1.18 才能使用您想要使用的支持泛型 + 动态类型。
随时随地看视频慕课网APP

相关分类

Go
我要回答