2016-02-22 16 views

答えて

10

TL; DR:賢く選択肢がが存在するためString.index/2が意図的に不足しています。非常に頻繁にString.split/2は根本的な問題を解決し、より良いパフォーマンスを実現します。

  • ここではUTF-8文字列を使用していると仮定し、非ASCII文字をきちんと扱うことを想定しています。

  • エリクサーは高速なコードを推奨します。 String.index/2で解決しようとする問題は、コードの可読性を損なうことなくパフォーマンスを大幅に向上させる、よりスマートな方法で解決できることが判明しました。

  • スマートな解決策は、String.split/2や他の同様のStringモジュール関数を使用することです。 String.split/2は、文字列を正しく扱いながらバイトレベルで動作します。両方の引数が文字列なので間違ってはいけません! String.index/2は、文字列全体をゆっくりと探索するグラフェンレベルで動作する必要があります。

  • この理由から、String.index/2は、既存の関数できちんと解決できない非常に魅力的な使用例が出てこない限り、言語に追加される可能性は低いです。

  • はそのことにも万能薬-LANGコアの議論を参照してください:サイドノートで https://groups.google.com/forum/#!topic/elixir-lang-core/S0yrDxlJCss

  • は、エリクサーはその成熟Unicodeサポートではかなりユニークです。ほとんどの言語はコードポイントレベル(大まかに「文字」)で動作しますが、Elixirはより高いレベルの文体の概念を扱います。 Graphemesは、ユーザーが1つのキャラクターと認識しているものです(「キャラクター」をより実践的に理解することができます)。Graphemesには、複数のコードポイントが含まれていてもかまいません(これは、1バイト以上を含むことができます)。

    最後に

、私たちは本当にインデックスが必要な場合:

case String.split("[email protected]", "domain", parts: 2) do 
    [left, _] -> String.length(left) 
    [_] -> nil 
end 
+1

はのstring.Split/2は廃止されていますか?私は最新のドキュメントでsplit/1とsplit/3しか見ることができません。 –

10

私は、このための任意のエリクサーラッパーだと思う、#1119が表示されません。

あなたはそれまで直接:binary.matchを呼び出すことができます。

iex(1)> :binary.match "[email protected]", "@" 
{9, 1} 
iex(2)> :binary.match "[email protected]", "domain" 
{10, 6} 

戻り値はインデックスと一致の長さを含むタプルです。 |> elem(0)にパイプするか、パターンマッチングを使用してインデックスだけを抽出することができます。

:binary.matchは、文字列に部分文字列が見つからない場合は:nomatchを返します。

4

あなたは、文字列内の場所をしたい使用する場合は、:binary.match/3

{index, length} = :binary.match("aéiou", "o")  
{4, 1} 

を使用して、バイトのインデックスを取得することができます。

"aéiou" |> to_char_list() |> Enum.find_index(&(&1 == ?o)) 
3 

Stringモジュールのドキュメントは、バイト長と文字列の長さの違いを説明。

5

あなたはRegex.run/3を使用し、オプションとしてreturn: :indexそれを渡すことができます:

iex(5)> [{start, len}] = Regex.run(~r/abc/, " abc ", return: :index) 
[{1, 3}] 
0
# index (as INSTR from basic...) 

... 
import IO, except: [inspect: 1] 
puts index "algopara ver", "ver" 

def index(mainstring, searchstring) do 
    tuple = (:binary.match mainstring, searchstring) 
    if tuple === :nomatch do 
     0 
    else 
     elem(tuple,0) 
    end 
end 
... 

9 
+0

これまでのすべての回答のおかげで.. –

関連する問題