如何合并/压缩不同类型的通用列表(并将结果强制转换为字典)

本文关键字:结果 列表 转换 字典 合并 何合并 压缩 同类型 | 更新日期: 2023-09-27 18:05:53

我需要从一些excel表格中读取数据。excel表格中的数据已经格式化,我可以通过使用这种方法获得所需的数据。

这就是我正在做的:

using (var conn = new OleDbConnection(strBld.ToString()))
{
    conn.Open();
    IEnumerable<IDictionary<string, object>> excelDataRaw = 
        conn.Query("select * from [Curves$A:IT]").
        Cast<IDictionary<string, object>>();
    int i = 0;
    string previousKey = null;
    var curve = new List<IEnumerable<object>>();
    var excelData = new Dictionary<string, IDictionary<object, object>>();
    //var excelData = new Dictionary<string, IDictionary<string, decimal>>();
    foreach (var key in excelDataRaw.Select(dictionary => dictionary.Keys).
        ElementAt(i))
    {
        string key1 = key;
        // gets the data from one column within the excel file
        curve.Add(excelDataRaw.Select(col => col[key1]).
            Where(row => row != null).ToList());
        if (i % 2 == 0)
        {
            // store the column header
            previousKey = key;
        }
        if (i % 2 == 1)
        {
            // merge the data from the first column (keys)
            // with the data from the second column (values)
            IEnumerable<object> keys = curve[i - 1];
            IEnumerable<object> values = curve[i];
            // cast works but than you can't zip the lists together
            //IEnumerable<string> keys = curve[i - 1].Cast<string>();
            //IEnumerable<decimal> values = curve[i].Cast<decimal>();
            // zip them together on their index
            var dic = keys.Zip(values, (k, v) => new { k, v }).
                ToDictionary(x => x.k, x => x.v);
            if (previousKey != null)
            {
                if (!excelData.ContainsKey(previousKey))
                {
                    excelData.Add(previousKey, dic);
                }
            }
        }
        ++i;
    }
}

我从excel文件(excelDataRaw)中提取所有数据。然后,我选择所有属于一个列表(曲线)的数据,并将彼此属于的两个列表合并到一个字典(dic)中。最后的结果是一个字典(excelData),其中包含excel文件中的列头作为键(previousKey)和与该列头相关的数据作为字典(dic)。

我想从

转换字典(excelData)
Dictionary<string, IDictionary<object, object>> 

Dictionary<string, IDictionary<string, decimal>> 

,但是我不能将对象强制转换为字符串或十进制,也不能在将每个列表强制转换为所需类型后将列表压缩在一起以获得字典(dic)。有没有人知道如何达到预期的结果(类型)?

如何合并/压缩不同类型的通用列表(并将结果强制转换为字典)

ExcelDataRaw的类型为Dictionary<string, IDictionary<object, object>>,因此需要将IDictionary<object, object>作为值。您不能将Dictionary<string,decimal>转换为IDictionary<object,object>,因为dictionary不是协变接口-参见http://msdn.microsoft.com/en-us/library/dd469487.aspx。

解决方案是将ExcelDataRaw的类型更改为Dictionary<string, IDictionary<string, decimal>>,或者保持原样,并在尝试使用该字典中的值时将其转换为正确的类型:

foreach(var kv in ExcelDataRaw)
{
   Dictionary<string,decimal> convertedValue=kv.Value.ToDictionary(x=>(string)x.Key,x=>(decimal)x.Value);
   // or convert it even further down the road
   string lookup = "abc";
   decimal v = (decimal)kv.Value[lookup];
}

我找到了解决办法,我一定是忽略了昨天显而易见的事情。睡个好觉有时会有帮助:).

IEnumerable<object> keys = curve[i - 1];
IEnumerable<object> values =
    curve[i].Where(content => decimal.TryParse(content.ToString(), out num));
    Dictionary<string, decimal> dic =
        keys.Zip(values, (k, v) => new { k, v }).ToDictionary(
            x => (string)x.k, x => decimal.Parse(x.v.ToString()));
if (previousKey != null)
{
    if (!excelData.ContainsKey(previousKey))
    {
        excelData.Add(previousKey, dic);
    }
}