87984


elixirを3日前に勉強し始めた者です。  
elixirでリストの[]をつけたまま出力する方法が分からず困っています。  
コンソールでa = [1, 2]をタイプして[1, 2]と出力するように、関数内で処理したリストデータを[]をつけた状態でコンソールに出力したいです。  
例：

[code]

    defmodule Test do
      def func(input1, input2) do
        funcInside(input1, input2) 
      end
    
      # まず単純に第1引数と第2引数を掛け算して出力する
      defp funcInside(input1, input2) do
        item1 = hd input1
        item2 = hd input2
        result = item1 * item2
        IO.puts "#{outputList}" #　←　出力をどう書けばコンソールにリストのまま表示されるかわからない。 
      end
    
    #例１：
    Test.func([1], [2])
    #=> [2] ←コンソールに上記プログラムで処理した後のリストを表示したいです。
    #例2：
    Test.func([[1, 2, [[2]]]], [[3, 2, [[4]]]])
    #=> [[3, 4, [[8]]]] ←コンソールに上記プログラムで処理した後のリストを表示したいです。
    
[/code]

アドバイス頂けましたら幸いです。


CC BY-SA 4.0
2022-03-22T23:44:04.037
87971
2022-03-28T00:32:05.170
21034
question
elixir
elixirでリストの[]をつけたままコンソールに出力する方法がわからない


再帰とパターンマッチの話なのかなと思います。  
公式ドキュメントで該当しそうなのは↓の辺りになりそうです。

  * [List](https://hexdocs.pm/elixir/1.13/List.html)
  * [Recursion](https://elixir-lang.org/getting-started/recursion.html)
  * [Pattern matching](https://elixir-lang.org/getting-started/pattern-matching.html)

Elixirについて知っているわけではないのでより良い書き方があるかも知れませんが:

[code]

    defmodule Test do
      def func([], []), do: []
      def func([h1 | t1], [h2 | t2]), do: [func(h1, h2) | func(t1, t2)]
      def func(input1, input2), do: input1 * input2
    end
    
    # 例１：
    ex1 = Test.func([1], [2])
    # => [2] ←コンソールに上記プログラムで処理した後のリストを表示したいです。
    IO.inspect(ex1, charlists: :as_lists)
    
    # 例2：
    ex2 = Test.func([[1, 2, [[2]]]], [[3, 2, [[4]]]])
    # => [[3, 4, [[8]]]] ←コンソールに上記プログラムで処理した後のリストを表示したいです。
    IO.inspect(ex2, charlists: :as_lists)
    
[/code]

([paiza.io](https://paiza.io/projects/oVrtZSEdQ6znBdrW3hbhlw))

* * *

2つのリスト

[code]

    l1 = [2]
    l2 = [3]
    
[/code]

が在るとき、リストのままだと掛け算

[code]

    l1 * l2
    
[/code]

できないので、一旦パターンマッチで数値に分解

[code]

    [i1] = l1
    [i2] = l2
    
[/code]

した上で計算し

[code]

    r = i1 * i2
    
[/code]

てから元に戻す

[code]

    [r]
    
[/code]

というのが基本の考え方です。

実際の入力値となっているリストは上の例のように要素が1つではなく、また要素がリストだったりもするので、その部分を再帰的に処理している、というのが最初に書いたコードになります。

質問コード中の

[code]

    item1 = hd input1
    
[/code]

は、回答コード中では

[code]

    [item1|tail] = input1
    
[/code]

となっています。  
(`item1` 以外の部分(`tail`)も使うので)

* * *

例1についてのみ考えるのであれば、再帰が不要なので、

> 出力をどう書けばコンソールにリストのまま表示されるかわからない。

の部分を

[code]

    IO.inspect([result], charlists: :as_list)
    
[/code]

とすれば良いでしょう。  
(「リストのまま」というわけではなく、分解したリストを再構築しています)

* * *

(追記: コメントでの質問について)

リストを入力に受けて、一番左の要素(head)とそれ以外の要素のリスト(tail)に分ける、そしてtailを次の入力にする、という再帰処理しています。

このとき、要素数が1のリストを入力に受けると、tailは要素数が0の空リストになります。  
この空リストが次の入力になりますが、その時の処理を定義しているのが

[code]

      def func([], []), do: []
    
[/code]

の部分になります。

考え方は[こちら](https://elixir-lang.org/getting-started/recursion.html#reduce-and-
map-algorithms)と同じなので、私の説明が分かりにくければそちらも参照してみてください。


CC BY-SA 4.0
2022-03-23T09:16:59.333
87984
2022-03-28T00:32:05.170
2022-03-28T00:32:05.170
2808
2808
87971
answer