Swift 数组常用的方法( filter、map、flatMap、reduce、sorted、forEach、contains、indexOf、prefix、suffix、dropFirst等)

一、filter方法:可以过滤数组中不满足筛选条件的元素,返回满足筛选条件的元素所组成的数组。

func filter(_ isIncluded: (UInt8) throws -> Bool) rethrows -> [UInt8]

filter方法参数是一个闭包,闭包返回值是Bool类型,当满足筛选条件的时闭包才有返回值,filter返回值是一个<T>的泛型数组

用法如下:

        let array = [1,2,3,4]
        let filteredArray = array.filter{$0 > 2}
        for i in filteredArray {//实际相当于for i in [3,4], 最后输出 3 和 4
            print(i)
        }

二、map方法

map方法将原来数组中元素映射到一个新的数组中:

func map<T>(_ transform: (T) throws -> T) rethrows -> [T]

map方法参数是一个闭包,闭包中可以执行相应的逻辑,执行完毕后返回一个<T>泛型数组 

        let array = [1,2,3,4]
        let mappedArray = array.map{$0 * 10}
        for i in mappedArray {
            print(i)//会输出10、20、30、40
        }

在工程中,我们常常会定义自己的类,有时候需要单独获取这些类的某个属性。习惯做法是用循环语句取出数组中的所有类的实例,然后把这些属性存到一个数组中,有了map函数后代码会变得非常简单。

例如,我们自定义了一个学生类,它有两个属性:名字和年龄,通过狗在其给这两个属性赋值:

    struct student {
        var name: String
        var age: Int
    }

现在新建一个student的类型的数组,里面放了四个学生的实例:

   let studentArr:[Student] = [Student(name: "张三", age: 13),
                               Student(name: "李四", age: 14),
                               Student(name: "王五", age: 15),
                               Student(name: "赵六", age: 16)]

现在我们来获取所有学生的名字,使用传统的方法:

    var nameArr: [String] = []
    for student in studentArr {
        nameArr.append(student.name)
    }
    for name in nameArr {
        print(name)//输出张三、李四、王五、赵六
    }

使用map函数:

    let nameArr = studentArr.map{$0.name}
    for name in nameArr {
        print(name)//输出张三、李四、王五、赵六
    }

可以看出map方法即高效,又容易理解

三、flatMap方法

flatMap可用于可选型与数组,可选型中的faltMap会把嵌套的可选型封装成一个可选型,而数组中的flatMap会检测数组中有没有嵌套的数组,把嵌套的数组解构再重组成一个数组。

func flatMap<SegmentOfResult>(_ transform: (T) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence

比如你通过不同额解构得到了两组数组,一组是尺寸,一组是颜色,如果需要混合两种数据,可能会这样做:

        let sizes = ["S","M","L"]
        let colors = ["red","black","white"]
        let groups = sizes.map { size in
            colors.map({ color in
                return (size  + " " + color)
            })
        }
        print(groups)

控制台输出: [["S red", "S black", "S white"], ["M red", "M black", "M white"], ["L red", "L black", "L white"]],我们需要的是一个所有组合的一维数组,但是得到的是一个嵌套的二维数组,

当然也是可以实现的,我们用for循环来实现

        let sizes = ["S","M","L"]
        let colors = ["red","black","white"]
        var groups: [String] = []
        for size in sizes {
            for color in colors {
                groups.append(size+color)
            }
        }
        print(groups)

控制台输出:["Sred", "Sblack", "Swhite", "Mred", "Mblack", "Mwhite", "Lred", "Lblack", "Lwhite"],这样实现起来会比较麻烦,不得不同样遍历两次,代码很难读,并且且套本来并没有发挥任何作用,如果你只需要底层数据,那么在最外层使用flatMap代替map:

        let groups = sizes.flatMap { size in
            colors.map({ color in
                return (size  + " " + color)
            })
        }

控制台输出:["S red", "S black", "S white", "M red", "M black", "M white", "L red", "L black", "L white"],现在嵌套已经被解除了

四、reduce方法

reduces方法可以把数组编程一个元素。首先需要指定一个初始值,然后在闭包中写一个reduce规则,接着reduce方法就会开始递归地对数组中的元素进行闭包中的运算,直到运算出最后一个结果,实例如下:

func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result

接收两个参数,一个为类型Result的初始值,另一个为把类型为Result的元素和类型为Element的元素组合成一个类型为Result的值的函数。

最终结果整个数组就变成了一个类型为Result的值。

        let array = [1,2,3,4]
        let result = array.reduce(0, {$0 + $1})
        //简化写法
        let result = array.reduce(0, +)
        print(result)//输出10

需要注意的是combine函数的两参数类型不同,$0为计算结果类型,$1为数组元素类型。

下面是reduce的三种用法。其实都一样,只是第二种更简洁,但是比较难懂,这两个方法都是返回数组中有多少个不相同的数。

extension Array where Element: Comparable {
    func countUniques() -> Int {
        let sorted = self.sorted(by: <)
        let initial: (Element?, Int) = (.none, 0)
        let reduced = sorted.reduce(initial) { (result, item) -> (Element?, Int) in
            if result.0 == item {
                return (item, result.1)
            }else {
                return (item, result.1+1)
            }
        }
        return reduced.1
    }
    //第二种
    func countTheUnique() -> Int {
        let sorted = self.sorted(by: <)
        let initial: (Element?, Int) = (.none, 0)
        let result = sorted.reduce(initial, {($1, $0.0 == $1 ? $0.1 : $0.1+1)})
        return result.1
    }
    //第三种可以一行代码完成
    func countUnique() -> Int {
        return self.sorted(by: <).reduce((.none, 0), {($1, $0.0 == $1 ? $0.1 : $0.1+1)}).1
    }
}
 
print([10,2,3,4,5,5,5,1].countTheUnique()) // 6
print([10,2,3,4,5,5,5,1].countUnique())    // 6
print([10,2,3,4,5,5,5,1].countUniques())   // 6

五、sorted方法

sorted方法接受另一个函数作为参数,这个参数是一个决定两个元素谁放在前面的函数型参数,默认是使用小于号的比较。通常会把排序函数写成一个闭包,闭包会被不停的调用,在内部采用了快速排序或者其它任意的排序方法。

func sorted(by areInIncreasingOrder: (Int, Int) throws -> Bool) rethrows -> [Int]
        let array = [3,1,2,4]
        let sortedArr = array.sorted{$0 < $1}
        //简写,默认从小到大
        let sortedArr = array.sorted()
        print(sortedArr)//输出 [1, 2, 3, 4]

六、forEach

        let array = [1,2,3,4]
        array.forEach {
            if $0 == 3 {
                return
            }
            print($0)//输出1,2,4
        }

注意:forEach闭包中的return语句只会从当前的闭包中返回,并不会中断整个遍历

七、contains方法

如果给定的数组中存在特定的元素,则contains方法就会返回true,否则返回false。

        let array = [1,2,3,4]
        print(array.contains(1))//输出true

八、index()方法

        let array = [1,2,3,4]
        //当前值的下标
        print(array.index(of: 2)!)//输出1
        //当前值的下标+1
        print(array.index(after: 1))//输入2
        //当前值的下标-1
        print(array.index(before: 1))//输出1
        //给定一个索引+2
        print(array.index(array.startIndex, offsetBy: 2))//输出2
        //给定一个缩影+2 不超出最大索引
        print(array.index(array.startIndex, offsetBy: 2, limitedBy:  array.endIndex)!)//输出2

九、prefix与suffix方法

        let array = [1,2,3,4]
        print(array.prefix(2))//输出[1,2]
        print(array.suffix(2))//输出[3,4]
        print(array.prefix(upTo: 3))//输出[1,2,3]
        print(array.suffix(from: 1))//输出[2,3,4]

十、dropFirst、dropLast方法

dropFirst返回的是除首元素之外的片段,dropLast返回的是除尾元素之外的片段

        let array = [1,2,3,4]
        print(array.dropFirst())//输出[2,3,4]
        print(array.dropLast())//输出[1,2,3]
        print(array.dropFirst(2))//输出[3,4]
        print(array.dropLast(2))//输出[1,2]

 

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当然可以,以下是一些 Java 8 Stream API 常用方法的代码例子: 1. filter: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); 2. map: List<String> words = Arrays.asList("hello", "world"); List<Integer> wordLengths = words.stream() .map(String::length) .collect(Collectors.toList()); 3. flatMap: List<List<Integer>> numbers = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5, 6)); List<Integer> flattenedNumbers = numbers.stream() .flatMap(List::stream) .collect(Collectors.toList()); 4. distinct: List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 4, 5, 3); List<Integer> distinctNumbers = numbers.stream() .distinct() .collect(Collectors.toList()); 5. sorted: List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6, 5); List<Integer> sortedNumbers = numbers.stream() .sorted() .collect(Collectors.toList()); 6. peek: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> doubledNumbers = numbers.stream() .peek(n -> System.out.println("Doubling " + n)) .map(n -> n * 2) .collect(Collectors.toList()); 7. limit: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> limitedNumbers = numbers.stream() .limit(3) .collect(Collectors.toList()); 8. skip: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> skippedNumbers = numbers.stream() .skip(2) .collect(Collectors.toList()); 9. reduce: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int sum = numbers.stream() .reduce(0, Integer::sum); 10. collect: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> collectedNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList());

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值