는, 정의 고유 키하여 이러한 값이 {DbName,Date}
를 사용하는 그룹이며, 각 키에서 항목 목록으로 맵핑을 작성하십시오.
다른 것을하기 전에이 고유 키를 나타내는 클래스를 만들어 IEquatable<T>
interface을 구현하도록해야합니다. 이렇게하면 Equals
메서드를 데이터베이스 인스턴스와 데이터베이스 이름이 동일한 두 인스턴스에서 호출하면 true
이 반환되며 .NET 매핑 구문이 제대로 작동하는 데 필요합니다. 이제
/// <summary>
/// Represents a unique journal info.
/// This class implements value-type comparison semantics.
/// </summary>
class JournalInfo : IEquatable<JournalInfo>
{
private readonly string _dbName;
/// <summary>Gets the database name.</summary>
public string DbName
{ get { return _dbName; } }
private readonly DateTime _date;
/// <summary>Gets the date.</summary>
public DateTime Date
{ get { return _date; } }
/// <summary>Initializes a new instance of the <see cref="JournalInfo"/> class.</summary>
public JournalInfo(string db, DateTime date)
{
_dbName = db; _date = date;
}
#region Equals overrides to ensure value-type comparison semantics
// a lot of plumbing needs to be done here to solve a simple task,
// but it must be done to ensure consistency in all cases
/// <summary>Determines whether the specified <see cref="JournalInfo" /> is equal to this instance.</summary>
public bool Equals(JournalInfo other)
{
if (object.ReferenceEquals(other, null))
return false;
else
return this.DbName == other.DbName && this.Date == other.Date;
}
/// <summary>Determines whether the specified <see cref="System.Object" /> is equal to this instance.</summary>
public override bool Equals(object other)
{
return this.Equals(other as JournalInfo);
}
/// <summary>Returns a hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</summary>
public override int GetHashCode()
{
var hash = 17;
if (this.DbName != null) hash += this.DbName.GetHashCode();
hash = hash * 31 + this.Date.GetHashCode();
return hash;
}
public static bool operator ==(JournalInfo a, JournalInfo b)
{
if (object.ReferenceEquals(a, null))
return object.ReferenceEquals(b, null);
return ((JournalInfo)a).Equals(b);
}
public static bool operator !=(JournalInfo a, JournalInfo b)
{
if (object.ReferenceEquals(a, null))
return !object.ReferenceEquals(b, null);
return !((JournalInfo)a).Equals(b);
}
#endregion
}
이 클래스를 준비, 당신은 JournalEntry
클래스를 생성하는 데 사용할 수 있습니다 :
class JournalEntry
{
public int LineNumber { get; set; }
public JournalInfo Info { get; set; }
public Decimal Amount { get; set; }
}
장소에를 갖는, 당신은 지금 그룹에이 값을 LINQ를 사용에 매핑 할 수 있습니다 항목의 목록 :이 덤프 루프를 사용할 수 있습니다 지금
var path = "input.txt";
var culture = System.Globalization.CultureInfo.InvariantCulture;
Dictionary<JournalInfo, List<JournalEntry>> map =
File.ReadLines(path) // lazy read one line at a time
.Skip(1) // skip header
.Select(line => line.Split(',')) // split into columns
.Select((columns, lineNumber) => new JournalEntry()
{ // parse each line into a journal entry
LineNumber = lineNumber,
Info = new JournalInfo(
columns[1],
DateTime.ParseExact(columns[2], "MM/dd/yyyy", culture)),
Amount = decimal.Parse(columns[3], culture)
})
.GroupBy(entry => entry.Info) // group by unique key
.ToDictionary(grouping => grouping.Key, grouping => grouping.ToList());
는 콘솔 :
당신의 입력 파일의 경우,이 코드를 인쇄해야합니다 :
Journal: DB1 - 12.08.2013
- Line 6, Amount = 1,00
- Line 7, Amount = 1,00
Journal: DB1 - 14.10.2013
- Line 1, Amount = 1,00
- Line 5, Amount = 1,00
Journal: DB2 - 12.08.2013
- Line 2, Amount = 1,00
- Line 4, Amount = 1,00
Journal: DB3 - 12.03.2013
- Line 0, Amount = 1,00
- Line 3, Amount = 1,00
1) 귀하의 구문 분석 코드가 그대로 잘입니다. * .csv 파일을 한 줄씩 읽어야합니다. 2) 데이터를 "집계"하려면 목록을 사용할 수 있습니다 (예 : 각 데이터베이스마다 하나의 목록). IMHO ... – paulsm4
[여기] (http://filehelpers.sourceforge.net/)는 CSV 파일을 다른 형식으로 파싱하는 데 환상적이며 훌륭한 무료 오픈 소스 구성 요소입니다. –
이 파일의 크기는 얼마입니까? 쉽게 메모리에 맞출 수 있습니까? 정렬되지 않은 경우 일치하는 저널을 찾으려면 어느 정도까지 역 추적해야 할 것으로 예상됩니까? 작은 파일 인 경우 사전을 사용하면됩니다. – Groo