2017-02-11 4 views
3

私はプログラミングが新しく、いくつかのランダム関数を記述して遊んできました。IEnumerable項目がLINQを使用して使用される前に消えています。

私はeratosthenesふるいに基づいて緩やかに機能する以下の機能を書いています。最初は、私はupdatedEntries IEnumerableに問題がありました。

updatedEntitesは、(私が収集した遅延実行とは何か - 'current'はnullでしたが、結果ビューには関連する項目が含まれていましたが)RemoveWhereがoddPrimesAndMultiplesに適用されたときにupdatedEntries oddPrimesAndMultiplesの項目にまだリンクされている理由がわからなくても消えました。 (私はもちろん、何が起こっているのか完全に誤解している可能性があります。問題は完全に別のものかもしれません)

updatedEntriesをIEnumerableではなくListに変更しても問題は発生しません。私はSortedSetを使っているという事実をより良く利用するためにLINQを使わないで、LINQを使用していますが、なぜ問題が最初に発生したのかを知りたいのですが!

public static IEnumerable<int> QuickPrimes() 
     { 
      int firstPrime = 2; 
      int firstOddPrime = 3; 

      int currentValue = firstOddPrime; 
      int currentMinimumMultiple; 

      SortedSet<Tuple<int, int>> oddPrimesAndMultiples = new SortedSet<Tuple<int, int>>() { new Tuple<int, int> (firstOddPrime, firstOddPrime) }; 
      IEnumerable<Tuple<int, int>> updatedEntries; 

      yield return firstPrime; 
      yield return firstOddPrime; 

      while (true) 
      { 
       currentMinimumMultiple = oddPrimesAndMultiples.First().Item1; 
       while (currentValue < currentMinimumMultiple) 
       { 
        yield return currentValue; 
        oddPrimesAndMultiples.Add(new Tuple<int, int> (currentValue * 3, currentValue)); 
        currentValue += 2; 
       } 

       updatedEntries = oddPrimesAndMultiples.Where(tuple => tuple.Item1 == currentMinimumMultiple) 
                 .Select(t => new Tuple<int, int>(t.Item1 + 2 * t.Item2, t.Item2)); 

       oddPrimesAndMultiples.RemoveWhere(t => t.Item1 == currentMinimumMultiple); 
       oddPrimesAndMultiples.UnionWith(updatedEntries); 
       currentValue += 2; 
      } 
     } 

と私は機能をテストしてるところメイン::事前に

static void Main(string[] args) 
     { 
      foreach(int prime in Problems.QuickPrimes()) 
      { 
       Console.WriteLine(prime); 
       if (prime > 20) return; 
      } 
     } 

感謝

は、ここに私のコードです!

+0

yieldキーワードを使用するIEnumerableでは、実際には非常に異なる結果が得られます。それを賢明に使う。 –

+0

私はこれを理解しているかどうかを見てみましょう、あなたのコードは今のところ動作していますが、それ以前は、updatedEntriesの割り当てで正しい ".ToList()"呼び出しがなかったためではありませんでしたか? –

+0

問題を[MCVE]でお知らせください。現在の投稿では、コードに問題があるかどうかは明らかではありません。 –

答えて

1

トラップはupdatedEntriesが1行で定義されていますが、実際にはに実行されます。 (Linqpadから)このコードスニペットを参照して、基本に戻る、それを持って来るために

var ints = new SortedSet<int>(new[] { 1,2,3,4,5,6,7,8,9,10}); 

var updatedEntries = ints.Where(i => i > 5); // No ToList()! 
updatedEntries.Dump(); 

これは6, 7, 8, 9, 10を示しています。

ints.RemoveWhere(i => i > 7); 
updatedEntries.Dump(); 

updatedEntriesが再実行されているため、今これは、6, 7を示しています。あなたが最初のリスト6, 7, 8, 9, 10を追加することを期待しながら、

​​

これは、6, 7を追加します。

したがって、IEnumerableを定義するときは、いつ実際に実行されるのかを意識する必要があります。特定のポイントでプログラムの状態に常に作用します。

関連する問題