1

LINQの個別の機能について、多くの異なるソリューションを読みました。これらを組み合わせると、問題が解決します。私の問題は、LINQステートメントを正しくまとめる方法についてまだ頭を悩ませていることです。構文を正しく理解できないようです。または、情報がまとまり、私が望むものとは異なります。

これの半分が重複しているように思われる場合は、事前にお詫び申し上げます。私の質問は、ファイルを読むだけではありません。すべて同じクエリに入れたいのですが。

でも要点は..

セミコロンで区切られたデータ列を含むテキストファイルを読み込んでいます。

例は次のとおりです。

US;Fort Worth;TX;Tarrant;76101
US;Fort Worth;TX;Tarrant;76103
US;Fort Worth;TX;Tarrant;76105
US;Burleson;TX;Tarrant;76097
US;Newark;TX;Tarrant;76071
US;Fort Worth;TX;Tarrant;76103
US;Fort Worth;TX;Tarrant;76105

これが私がこれまでに持っているものです:

var items = (from c in (from line in File.ReadAllLines(myFile)
    let columns = line.Split(';')
    where columns[0] == "US"
    select new
    {
        City = columns[1].Trim(),
        State = columns[2].Trim(),
        County = columns[3].Trim(),
        ZipCode = columns[4].Trim()
    })
    select c);

これは、ファイルの読み取りには問題なく機能します。しかし、その後の私の問題は、生データが必要ないことです。まとめが欲しい。

具体的には、市と州の組み合わせの発生回数と、郵便番号が表示される回数のカウントが必要です。

最終的にはそれからツリービューを作成します。私の目標は、次のようにレイアウトすることです。

- Fort Worth,TX (5)
       -  76101 (1)
       -  76103 (2)
       -  76105 (2)  

- Burleson,TX (1)
       - 76097 (1)

- Newark,TX (1)
     - 76071 (1)

他にやるべき処理があるので、私は木のことを遅くすることができます。

だから私の質問は:クエリ自体の特定の値のカウントをどのように組み合わせるのですか?GroupBy関数を知っていて、Aggregatesを見たことがありますが、正しく機能させることができません。これらすべての関数を1つのクエリにラップするにはどうすればよいですか?

編集:私は私の質問を間違った方法で尋ねたと思います。1つのクエリですべてを実行する必要があるという意味ではありません...1つのクエリでLINQを使用してこれを実行するための明確で、簡潔で、効率的な方法はありますか?そうでない場合は、ループに戻ります。

私が正しい方向に向けられることができれば、それは大きな助けになるでしょう。誰かがこれらすべてを行うためのより簡単なアイデアを考えているなら、私に知らせてください。

膨大な数の値を繰り返し処理したり、すべての行でRegex.Splitを使用したりすることは避けたかっただけです。

明確にする必要がある場合はお知らせください。

ありがとう!

*編集6/15***

私はそれを考え出した。答えてくれた人たちのおかげで助けになりましたが、私が必要としていたものではありませんでした。ちなみに、とにかくすべてを変更することになりました。LINQは、関連性がないため、他の方法よりも実際には遅くなりました。「1つのクエリにそれを含めるのはばかげている」と複数のコメントをした人たちに関しては、それは設計者の決定です。すべての「ベストプラクティス」がすべての場所で機能するとは限りません。ガイドラインです。私を信じてください、私は自分のコードを明確で理解しやすいものにしておきたいのですが、私がしたようにそれを行うための非常に具体的な理由もありました。

私は助けと方向性に感謝します。

以下は私が使用したが後で放棄したプロトタイプです。

    /* Inner LINQ query Reads the Text File and gets all the Locations.
     * The outer query summarizes this by getting the sum of the Zips 
     * and orders by City/State then ZIP */


var items = from Location in(
    //Inner Query Start
    (from line in File.ReadAllLines(FilePath)
    let columns = line.Split(';')
    where columns[0] == "US" & !string.IsNullOrEmpty(columns[4])
    select new
    {
    City = (FM.DecodeSLIC(columns[1].Trim()) + " " + columns[2].Trim()),
    County = columns[3].Trim(),
                   ZipCode = columns[4].Trim()
    }
    ))
    //Inner Query End
    orderby Location.City, Location.ZipCode  
                   group Location by new { Location.City, Location.ZipCode , Location.County} into grp
            select new
            {
            City = grp.Key.City,
            County = grp.Key.County,
            ZipCode = grp.Key.ZipCode,
            ZipCount = grp.Count()      
            };
4

3 に答える 3

3

File.ReadAllLinesを使用することの欠点は、ファイルを操作する前にファイル全体をメモリにプルする必要があることです。また、Columns[]の使用は少し不格好です。DynamicObjectの使用と、代替実装としてのファイルのストリーミングについて説明している私の記事を検討することをお勧めします。グループ化/カウント操作は、その議論の二次的なものです。

于 2012-06-15T18:41:47.360 に答える
1

すべてを 1 つのクエリにまとめても意味がありません。意味のあるものになるように、クエリを分割することをお勧めします。あなたの結果にこれを試してください

var grouped = items.GroupBy(a => new { a.City, a.State, a.ZipCode }).Select(a => new { City = a.Key.City, State = a.Key.State, ZipCode = a.Key.ZipCode, ZipCount = a.Count()}).ToList();

結果のスクリーンショット

ここに画像の説明を入力

編集

これは、同じ出力を与える 1 つの大きな長いクエリです。

var itemsGrouped = File.ReadAllLines(myFile).Select(a => a.Split(';')).Where(a => a[0] == "US").Select(a => new { City = a[1].Trim(), State = a[2].Trim(), County = a[3].Trim(), ZipCode = a[4].Trim() }).GroupBy(a => new { a.City, a.State, a.ZipCode }).Select(a => new { City = a.Key.City, State = a.Key.State, ZipCode = a.Key.ZipCode, ZipCount = a.Count() }).ToList();
于 2012-06-04T02:10:04.647 に答える
1
        var items = (from c in
                         (from line in File.ReadAllLines(myFile)
                          let columns = line.Split(';')
                          where columns[0] == "US"
                          select new
                                     {
                                         City = columns[1].Trim(),
                                         State = columns[2].Trim(),
                                         County = columns[3].Trim(),
                                         ZipCode = columns[4].Trim()
                                     })
                     select c);
        foreach (var i in items.GroupBy(an => an.City + "," + an.State))
        {
            Console.WriteLine("{0} ({1})",i.Key, i.Count());
            foreach (var j in i.GroupBy(an => an.ZipCode))
            {
                Console.WriteLine(" - {0} ({1})", j.Key, j.Count());

            }

        }
于 2012-06-04T02:08:20.367 に答える