我有一个不幸的动态列结构的平面文件。值中包含一个值,层次结构中的每个层都有自己的列。例如,我的平面文件可能类似于:
StatisticID|FileId|Tier0ObjectId|Tier1ObjectId|Tier2ObjectId|Tier3ObjectId|Status
1234|7890|abcd|efgh|ijkl|mnop|Pending
...
第二天同样的饲料可能类似于:
StatisticID|FileId|Tier0ObjectId|Tier1ObjectId|Tier2ObjectId|Status
1234|7890|abcd|efgh|ijkl|Complete
...
问题是,我并不关心所有层级;我只关心最后(底部)层的id,以及不属于层列的所有其他行数据。我需要将feed标准化为类似于此的东西以注入关系数据库:
StatisticID|FileId|ObjectId|Status
1234|7890|ijkl|Complete
...
什么是一种有效,易于阅读的机制,用于确定最后一层的对象ID,并按照描述组织数据?我所做的每一次尝试都让我感到尴尬。
我做过的一些事情:
IDictionary<string, int>
对象中进行引用,但再次可靠地收集动态列的序数是一个问题,而且这似乎是非常不具备的性能。答案 0 :(得分:1)
首先制作一个词典:
private Dictionary<int, int> GetColumnDictionary(string headerLine)
{
Dictionary<int, int> columnDictionary = new Dictionary<int, int>();
List<string> columnNames = headerLine.Split('|').ToList();
string maxTierObjectColumnName = GetMaxTierObjectColumnName(columnNames);
for (int index = 0; index < columnNames.Count; index++)
{
if (columnNames[index] == "StatisticID")
{
columnDictionary.Add(0, index);
}
if (columnNames[index] == "FileId")
{
columnDictionary.Add(1, index);
}
if (columnNames[index] == maxTierObjectColumnName)
{
columnDictionary.Add(2, index);
}
if (columnNames[index] == "Status")
{
columnDictionary.Add(3, index);
}
}
return columnDictionary;
}
private string GetMaxTierObjectColumnName(List<string> columnNames)
{
// Edit this function if Tier ObjectId is greater then 9
var maxTierObjectColumnName = columnNames.Where(c => c.Contains("Tier") && c.Contains("Object")).OrderBy(c => c).Last();
return maxTierObjectColumnName;
}
之后,它只是通过文件运行:
private List<DataObject> ParseFile(string fileName)
{
StreamReader streamReader = new StreamReader(fileName);
string headerLine = streamReader.ReadLine();
Dictionary<int, int> columnDictionary = this.GetColumnDictionary(headerLine);
string line;
List<DataObject> dataObjects = new List<DataObject>();
while ((line = streamReader.ReadLine()) != null)
{
var lineValues = line.Split('|');
string statId = lineValues[columnDictionary[0]];
dataObjects.Add(
new DataObject()
{
StatisticId = lineValues[columnDictionary[0]],
FileId = lineValues[columnDictionary[1]],
ObjectId = lineValues[columnDictionary[2]],
Status = lineValues[columnDictionary[3]]
}
);
}
return dataObjects;
}
我希望这会有所帮助(甚至一点点)。
答案 1 :(得分:0)
就个人而言,我不会尝试重新格式化您的文件。我认为最简单的方法是解析前面和后面的每一行。例如:
itemArray = getMyItems();
statisticId = itemArray[0];
fileId = itemArray[1];
//and so on for the rest of your pre-tier columns
//Then get the second to last column which will be the last tier
lastTierId = itemArray[itemArray.length -1];
因为你知道最后一层总是从最后一层开始,所以你可以从最后开始,然后继续前进。这似乎比尝试重新格式化数据文件容易得多。
如果您确实想要创建新文件,可以使用此方法获取要写出的数据。
答案 2 :(得分:0)
我不知道C#语法,但是有以下几点: