2

一部のデータは最もクリーンではありません。たとえば、ある人が 2 つの異なる方法で住所を入力した場合、出力には 2 回表示される可能性があります。1 回目は「RD」で、2 回目は「Road」です。

おかしなことに、データの半分が一方のレコードに表示され、半分が他方のレコードに表示されます。そう...

Johnny, Larsen Rd, Tuesday, 4 milk bottles
Johnny, Larsen Road, Tuesday, 3 milk bottles

ジョニーの火曜日の消費量は、実際には牛乳 7 本でした。これら 2 つのオブジェクトをあまり苦労せずにマージする LINQ を作成しようとしていますが、これまでのところこれだけです。

var records = report.GroupBy(r => r.Date)
    .Select(n => new MilkBottleRecord() {
        Name = report.First().Name,
        Address = report.First().Address,
        Date = report.First().Date,
        Bottles = n.Sum(x => x.Bottles),
    });

助言がありますか?

A) これは私たちのデータではないので、実際にはクリーンアップを行うことはできません。B) SQL クエリからではなく、CSV 経由でデータを取得しています。

また、上記のクエリで関連する情報は日付のみです。これは、前のクエリで別のアカウントを既に分離しているためです。それは問題ないので、ここに含めるのに時間をかける価値があるとは思いませんでした.

4

6 に答える 6

3

書くのが面倒なクエリを使用する代わりに、データベースを調べて重複レコードをマージしたほうがよいのではないでしょうか? これを行うと、クエリがより見栄えが良くなります。

于 2013-07-30T20:51:38.223 に答える
1

次のようなことを試すことができます:

IEqualityComparer<MilkBottleRecord> comparer = /* instantiate a comparer */
var records = report.GroupBy(x => x, comparer)
                    .Select(g => new MilkBottleRecord(g.Key) {
                        Bottles = g.Sum(x => x.Bottles))
                    });

基本的な考え方は、比較ロジックを外部化し、重要な情報を複製できるコピー コンストラクターを作成し、ボトル フィールドを Sum で上書きすることです。

于 2013-07-30T20:54:31.693 に答える
0

本当の答えは、データをサニタイズして正規化することです。住所で大通りの種類 (Road/Rd、Avenue/Av/Ave、Street/St、Drive/Dr、Len/Ln) をスペルアウトまたは省略形のどちらで使用するかを決定し、基準に準拠するようにデータを変更します。選択して重複除外します。

答えのもう 1 つの部分は、不変の識別子を使用してレコードを区別することです。「Larsen Road」に住む「Johnny」という名前の 2 人の異なる人物になる可能性があります。同じラーセン ロードである可能性さえあります。ジョンとニックネームのジョニーは、特定のラーセン ロードに住んでいるジョニーのそばを通り過ぎる 2 人のジョンが簡単に存在するほど一般的です。うまくいけば、それらは姓、および区画またはアパートの番号によって区別されますが、このデータのいずれかが疑わしいと思われる場合は、まだ問題があります. 解決策は、アカウント番号などの一意の識別子です。これにより、Larsen Road に住む Johnny という名前の 2 人の異なる人物を明確に区別したり、逆に、そうでなければ 1 人を間違える原因となる他の「一意の識別情報」の不一致を識別したりできます。 2人分。

LINQ は万能薬ではありません。LINQ を使用して汎用の正規化クエリを思いつくかもしれませんが、私はあなたに遅れをとってそれを維持したくありません。実世界のデータをコンピューターが照合できるものにサニタイズするためのツールは他にもあります。

于 2013-07-30T21:06:26.030 に答える
0

フルフィルメント会社は、CASSソフトウェアを使用して住所の修正と正規化を行っています。あなたが専門的に何かをしているなら、あなたはそれを調べるかもしれません。

それ以外の場合は、次のようなことができます。

string NormalizeAddress(string str)
{
    // should probably be a bit more intelligent than this, but maybe not.
    str = str.ToUpperInvariant();
    str = str.Replace ("ROAD", "RD");
    return str;
}

var records = report.GroupBy(r =>
                         Tuple.Create(r.Date, NormalizeAddress(r.Address)))
于 2013-07-30T20:53:40.417 に答える
0

データ構造を変更できない場合は、次のようなものはいかがですか

var records = report.GroupBy(r => r.Date)
    .Select(n => new MilkBottleRecord(report.First, n.Sum(x => x.Bottles)));

とコンストラクタ

MilkBottleReport(MilkBottleReport original, int newBottles); 
于 2013-07-30T20:57:06.420 に答える