サーチ…


備考

Listリンクされたリスト )は順次アクセスで輝きます

  • 第1要素にアクセスする
  • リストの前に追加する
  • リストの先頭から削除する

一方、 ランダムアクセス (つまり、n番目の要素を取得)と逆順にトラバースするのは理想的ではなく、 Arrayデータ構造でより良い運(およびパフォーマンス)を得ることができます。

範囲でリストを作成する

0.18.0

0.18.0より前に、 次のような範囲を作成することができます:

> range = [1..5]
[1,2,3,4,5] : List number
>
> negative = [-5..3]
[-5,-4,-3,-2,-1,0,1,2,3] : List number
0.18.0

In [1..5] 0.1.5.0 [1..5]構文が削除されました

> range = List.range 1 5
[1,2,3,4,5] : List number
>
> negative = List.range -5 3
[-5,-4,-3,-2,-1,0,1,2,3] : List number

この構文で作成される範囲は常にインクルーシブで、 ステップは常に1です。

リストの作成

> listOfNumbers = [1,4,99]
[1,4,99] : List number
>
> listOfStrings = ["Hello","World"]
["Hello","World"] : List String
>
> emptyList = []   -- can be anything, we don't know yet
[] : List a
>

Listリンクされたリスト )は::関数( "cons"と呼ばれる)によって構築され、頭と呼ばれる要素と頭の前に置かれる(おそらく空の)リストの2つの引数をとります。

> withoutSyntaxSugar = 1 :: []
[1] : List number
>
> longerOne = 1 :: 2 :: 3 :: []
[1,2,3] : List number
>
> nonemptyTail = 1 :: [2]
[1,2] : List number
>

Listは1つのタイプの値しか取ることができないので、 [1,"abc"]ようなものは不可能です。これが必要な場合は、タプルを使用してください。

> notAllowed = [1,"abc"]
==================================== ERRORS ====================================

-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm

The 1st and 2nd elements are different types of values.

8|              [1,"abc"]
               ^^^^^
The 1st element has this type:

    number

But the 2nd is:

    String

Hint: All elements should be the same type of value so that we can iterate
through the list without running into unexpected values.


> 

要素の取得

> ourList = [1,2,3,4,5]
[1,2,3,4,5] : List number
>
> firstElement = List.head ourList
Just 1 : Maybe Int
>
> allButFirst = List.tail ourList
Just [2,3,4,5] : Maybe (List Int)

Maybe型へのこのラッピングは、次のシナリオのために発生します。

List.headは空のリストに対して何を返すべきですか? (Elmには例外やnullがないことに注意してください)。

> headOfEmpty = List.head []
Nothing : Maybe Int
>
> tailOfEmpty = List.tail []
Nothing : Maybe (List Int)
>
> tailOfAlmostEmpty = List.tail [1] -- warning ... List is a *linked list* :)
Just [] : Maybe (List Int)

リストのすべての要素を変換する

List.map : (a -> b) -> List a -> List bは、リストの各要素に1つのパラメータ関数を適用し、変更された値を持つ新しいリストを返す上位関数です。

import String

ourList : List String
ourList = 
    ["wubba", "lubba", "dub", "dub"]

lengths : List Int
lengths = 
    List.map String.length ourList
-- [5,5,3,3]

slices : List String
slices =
    List.map (String.slice 1 3) ourList
-- ["ub", "ub", "ub", "ub"]

要素のインデックスを知る必要があれば、 List.indexedMap : (Int -> a -> b) -> List a -> List bを使うことができますList.indexedMap : (Int -> a -> b) -> List a -> List b

newList : List String
newList =
    List.indexedMap (\index element -> String.concat [toString index, ": ", element]) ourList
-- ["0: wubba","1: lubba","2: dub","3: dub"] 

リストのフィルタリング

List.filter : (a -> Bool) -> List a -> List aは、任意の値からブール値への1パラメータ関数をとり、その関数を与えられたリストのすべての要素に適用する高次関数です。関数がTrueを返す要素だけを保持します。 List.filterが最初のパラメータとして取る関数は、しばしば述語と呼ばれます。

import String

catStory : List String
catStory = 
    ["a", "crazy", "cat", "walked", "into", "a", "bar"]

-- Any word with more than 3 characters is so long!
isLongWord : String -> Bool
isLongWord string =
    String.length string > 3

longWordsFromCatStory : List String
longWordsFromCatStory = 
    List.filter isLongWord catStory

elm-replこれを評価してください:

> longWordsFromCatStory
["crazy", "walked", "into"] : List String
>
> List.filter (String.startsWith "w") longWordsFromCatStory
["walked"] : List String

リスト上のパターンマッチング

リストを構築するためのコンストラクタが中置関数::であるという点で、他のデータ型のようにリストをマッチさせることは可能です。 (その動作の詳細については、リストの作成の例参照してください)。

matchMyList : List SomeType -> SomeOtherType
matchMyList myList = 
    case myList of
        [] -> 
            emptyCase

        (theHead :: theRest) ->
            doSomethingWith theHead theRest

私たちは望むのと同じくらい多くの要素をリスト内で一致させることができます:

hasAtLeast2Elems : List a -> Bool
hasAtLeast2Elems myList =
    case myList of
        (e1 :: e2 :: rest) -> 
            True
    
        _ -> 
            False

hasAtLeast3Elems : List a -> Bool
hasAtLeast3Elems myList =
    case myList of
        (e1 :: e2 :: e3 :: rest) -> 
            True
    
        _ -> 
            False

リストからn番目の要素を取得する

Listは "ランダムアクセス"をサポートしていません。つまり、リストの5番目の要素を最初の要素よりも取得するためには多くの作業が必要です。その結果、 List.get nth list関数はありません。 1つは、最初からすべての道を行く必要があります( 1 -> 2 -> 3 -> 4 -> 5 )。

ランダムアクセスが必要な場合はArrayなどのランダムアクセスデータ構造でより良い結果(およびパフォーマンス)が得られるかもしれません。最初の要素を取ると、たとえば1000分の1を取るのと同じ作業量が必要になります。 (複雑さO(1))。

それにもかかわらず、n番目の要素を取得することは可能です(ただし、推奨しません)

get : Int -> List a -> Maybe a
get nth list =
    list
        |> List.drop (nth - 1)
        |> List.head

fifth : Maybe Int
fifth = get 5 [1..10]
--    = Just 5

nonexistent : Maybe Int
nonexistent = get 5 [1..3]
--          = Nothing

この場合も、 nth引数が大きくなるほど、これはかなり多くの作業を必要とします。

リストを単一の値に減らす

Elmでは、関数を減らすことを「折り畳み」と呼びます。左からfoldl 、右からfoldr値を「折りたたむ」2つの標準的な方法があります。

> List.foldl (+) 0 [1,2,3]
6 : number

foldlfoldrの引数は次のとおりです。

  • 減少関数newValue -> accumulator -> accumulator
  • アキュムレータ開始値
  • 削減するリスト

カスタム関数を使用したもう1つの例:

type alias Counts =
    { odd : Int
    , even : Int
    }

addCount : Int -> Counts -> Counts
addCount num counts =
    let
        (incOdd, incEven) =
            if num `rem` 2 == 0
                then (0,1)
                else (1,0)
    in
        { counts
            | odd = counts.odd + incOdd
            , even = counts.even + incEven
        }

> List.foldl
      addCount
      { odd = 0, even = 0 }
      [1,2,3,4,5]
{ odd = 3, even = 2 } : Counts

上記の最初の例では、プログラムは次のようになります。

List.foldl (+) 0 [1,2,3]
3 + (2 + (1 + 0))
3 + (2 + 1)
3 + 3
6
List.foldr (+) 0 [1,2,3]
1 + (2 + (3 + 0))
1 + (2 + 3)
1 + 5
6

(+)ような可換性の関数の場合、実際には違いはありません。

しかし、何が起こっているか見てみましょう(::)

List.foldl (::) [] [1,2,3]
3 :: (2 :: (1 :: []))
3 :: (2 :: [1])
3 :: [2,1]
[3,2,1]
List.foldr (::) [] [1,2,3]
1 :: (2 :: (3 :: []))
1 :: (2 :: [3])
1 :: [2,3]
[1,2,3]

値を繰り返してリストを作成する

> List.repeat 3 "abc"
["abc","abc","abc"] : List String

List.repeat任意の値を与えることができます:

> List.repeat 2 {a = 1, b = (2,True)}
[{a = 1, b = (2,True)}, {a = 1, b = (2,True)}]
  : List {a : Int, b : (Int, Bool)}

リストの並べ替え

既定では、 List.sortは昇順にソートされます。

> List.sort [3,1,5]
[1,3,5] : List number

List.sortは、 comparableリスト要素が必要です。すなわち、意味: StringCharnumberInt及びFloat )、 Listcomparableまたはタプルcomparable

> List.sort [(5,"ddd"),(4,"zzz"),(5,"aaa")]
[(4,"zzz"),(5,"aaa"),(5,"ddd")] : List ( number, String )

> List.sort [[3,4],[2,3],[4,5],[1,2]]
[[1,2],[2,3],[3,4],[4,5]] : List (List number)

List.sortBoolやオブジェクトのリストをソートすることはできません。それについては、カスタムコンパレータでリストをソートするを参照してください。

> List.sort [True, False]
-- error, can't compare Bools

カスタムコンパレータでリストをソートする

List.sortWith使用すると、リストを任意の形状のデータで並べ替えることができます。比較関数を使用してリストを並べ替えることができます。

compareBools : Bool -> Bool -> Order
compareBools a b =
    case (a,b) of
        (False, True) ->
            LT

        (True, False) ->
            GT

        _ ->
            EQ
        
> List.sortWith compareBools [False, True, False, True]
[False, False, True, True] : List Bool

リストを元に戻す

注: Listの性質上、これはあまり効率的ではありません(後述の「備考」を参照)。 リスト構築するよりも、リストを最初から「正しい」方法で構築し、それを逆にする方が良いでしょう。

> List.reverse [1,3,5,7,9]
[9,7,5,3,1] : List number

リストを降順で並べ替える

デフォルトでは、 List.sortcompare関数を使用して昇順にソートします。

降順でソートするには、効率的なソートと効率の悪いソートの2つの方法があります。

  1. 効率的な方法List.sortWithと降順比較関数。
descending a b =
    case compare a b of
      LT -> GT
      EQ -> EQ
      GT -> LT

> List.sortWith descending [1,5,9,7,3]
[9,7,5,3,1] : List number
  1. 非効率的な方法(落胆!)List.sortそしてList.reverse
> List.reverse (List.sort [1,5,9,7,3])
[9,7,5,3,1] : List number

派生値でリストをソートする

List.sortByでは、要素に対して関数を使用し、その結果を比較に使用できます。

> List.sortBy String.length ["longest","short","medium"]
["short","medium","longest"] : List String
-- because the lengths are: [7,5,6]

また、レコードアクセサでうまく動作します:

people =
    [ { name = "John", age = 43 }
    , { name = "Alice", age = 30 }
    , { name = "Rupert", age = 12 }
    ]

> List.sortBy .age people
[ { name = "Rupert", age = 12 }
, { name = "Alice", age = 30 }
, { name = "John", age = 43 }
] : List {name: String, age: number}

> List.sortBy .name people
[ { name = "Alice", age = 30 }
, { name = "John", age = 43 }
, { name = "Rupert", age = 12 }
] : List {name: String, age: number}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow