zoukankan      html  css  js  c++  java
  • Enum、Stream

    Enum

      其常见用法见:https://cloud.tencent.com/developer/section/1116852

      在sort时,如果要获得稳定的排序结果,要使用<= 而不是 <。

    Stream

      Stream是延迟处理的,而Enum是贪婪的,则意味着传给它一个收集,它会默默计算那个收集的所有内容。如:

    [ 1, 2, 3, 4, 5]
    |> Enum.map(&(&1 * &1))
    |> Enum.with_index
    |> Enum.map( fn {value, index} -> value - index end )
    |> IO.inspect        #=> [ 1, 3 ,7, 13, 21 ]
        #第一个map函数接受原始列表并生成一个新列表,其元素值是原来的平方。...如此下去最终生成了四个列表
    
    s = Stream.map [ 1, 3, 5, 7 ], &(&1 + 1)     #s不是一个列表
    Enum.to_list s        #这样使用 => [ 2, 4, 6 ,8 ]
    
    #我们通常这样写
    [ 1, 2, 3, 4 ]
    |> Stream.map(&(&1 * &1))
    |> Stream.map(&(&1 + 1))
    |> Stream.filter( fn x -> rem(x, 2) == 1 end )            #rem求余
    |> Enum.to_list        #转化为我们可见的    

      使用Stream没有中间结果,但是运行速度慢了两倍。适用于数据抵达的慢,但一直持续。使用Enum要等到所有数据到达后才能开始处理。使用流,只有有数据抵达就可以进行处理。

    自定义流

      Stream.cycle。它接受一个枚举类型参数,并返回一个包含该枚举类型参数元素的无限流。当到达结尾时会从头开始

    Stream.cycle(~w{ green white })
    |> Enum.take(5)        #green white green white green

      Stream.repeatedly。接受一个函数,在需要更新时调用该函数

      Stream.iterate。Stream.iterate( start_value, next_fun )生成一个无限流,第一个值是start_value,下一个值是调用next_fun函数以第一个值为参数生成的。

    Stream.iterate(0, &(&1 + 1)) |> Enum.take(5)        #[ 0, 1, 2, 3, 4]

      Stream.unfold。使用前两个参数计算下一个值

    Stream.unfold({0 ,1}, fn (f1, f2) -> {f1, {f2, f1 + f2}} end )
    |> Enum.take(8)
        #[ 0, 1 ,1, 2, 3, 5, 8, 13 ]

       Stream.resource。现在需要在流开始的时候才创建/读取数据,而在流结束的时候需要关闭数据。Stream.resource第一个参数接受一个函数,它会返回值。第二个参数也是接受一个函数,函数接受第一个函数的返回值。第三个参数函数关闭相关资源。

    Stream.resource(fn -> File.open("sample") end, 
                            fn file -> 
                                case IO.read(file, :line) do
                                    line when is_binary(line) -> { [line], file }
                                    _ -> { :halt, file }
                                end
                            end,
                            fn file -> File.close!(file) end )

    推导式

    for x <- [1, 2, 3, 4, 5], do: x * x
    
    for x <- [1, 2, 3, 4, 5], x < 4, do: x * x

      如果有两个生成器,则它们的操作是嵌套的。

    for x <- [1, 2], y <- [5, 6], do: {x, y}        #[ {1, 5}, {1, 6}, {2, 5}, {2, 6} ]

      后面的生成器可以使用前面的变量。

    min_maxes = [{1, 4}, {2, 3}, {10, 15}]
    for {min, max} <- min_maxes, n <- min..max, do: n
        #[1, 2, 3, 4, 2, 3 ,10, 11, 12, 13, 14, 15]

      例(使用了两个生成器和过滤器)。

    first8 = [1, 2, 3, 4, 5, 6, 7, 8]
    for x <- first8, y <- first8, x >= y, rem(x*y, 10) == 0, do: {x, y}    #x >= y 防止出现{2, 5}、{5, 2}

      推导式处理二进制。推导式中的变量只在其内部有效。

    for << ch <- "hello >>, do: ch        #返回的是列表[104, 101, 108, 108, 111]  iex显示为 'hello'
    for << ch <- "hello" >>, do: <<ch>>        #将编码转换为字符串  ["h", "e", ... ]

      推导式的返回值可以被into 改变。

    for x <- ~w{ cat dog }, into: Map.new, do: { x, String.upcase(x) }        # %{"cat" => "CAT", "dog" => "DOG" }
  • 相关阅读:
    微信公众平台开发教程(一) 微信公众账号注册流程
    DNS----域名解析系统
    C#编程总结(九)字符编码
    向大神学习
    C# 正则表达式
    js 正则表达式 取反
    H5 打开App
    Fiddler 过滤器的使用
    Fiddler 默认不能抓取页面信息的问题
    js 元素Dom新建并插入页面createElement
  • 原文地址:https://www.cnblogs.com/lr1402585172/p/11498748.html
Copyright © 2011-2022 走看看