映射来自不同IEnumerable的KeyValuePair

时间:2016-04-29 13:33:25

标签: c# algorithm linq lambda

问题:

我需要匹配reducedList与我的coreList匹配的数据,某种类型的联接,其中的密钥("年,Id,众议院......&#34) ;} reducedList将与我的coreList键(列表)匹配,这2个结果将合并到临时结果列表tempList中 - 这将是一列。

最终目标是使用我以后合并的数据填充整个Excel列,其中tempList中的第一个条目是标题,其余的是数据。

源代码已被注释掉,希望它有所帮助。

起初我的示例有效,但我需要一种更好的方法,可能更高效或更不同的方式来解决问题,我想我需要一种更好的映射方法/算法。

这是我的方法:

核心数据(一切):

Dictionary<String, Object> coreList = (Dictionary<String, Object>)_rawCoreList
    .Where(x => x.Key.Equals("ListOfCities"))
    .ToDictionary(x => x.Key, x => x.Value);//filter the property out I need

初始化数据(此列表稍后将与coreList匹配):

List<KeyValuePair<String, String>> reducedList = new List<KeyValuePair<string, string>>();

reducedList.Add(new KeyValuePair<string, string>("Id", "1. Heading"));
reducedList.Add(new KeyValuePair<string, string>("Year", "2. Heading"));
reducedList.Add(new KeyValuePair<string, string>("House", "3. Heading"));
reducedList.Add(new KeyValuePair<string, string>("Garage", "4. Heading"));
reducedList.Add(new KeyValuePair<string, string>("Basdlf", "The key does not exist"));
//reducedList.Add(new KeyValuePair<string, string>(null, null));//check for strange data

将简化列表中的属性名称(仅少数属性)与核心列表(所有属性)组合/匹配:

List<KeyValuePair<String/* Property-Name */, object /* Werte Property-Name */>> ergebnisListe = new List<KeyValuePair<string, object>>();//"" daraus ein Array machen

#region Matching with the reduced list

foreach (KeyValuePair<string, String> reducedListItem in reducedList)
{
    List<string> tempList = new List<string>();

    tempList.Add(reducedListItem.Value != null && !String.IsNullOrEmpty(reducedListItem.Value) ? reducedListItem.Value : "!Überschrift_FEHLER!");//adding the heading first

    #region Itereating through the core list, to get the rest for my data set(actually I need some mapping)

    foreach (KeyValuePair<string, Object> item in coreList)
    {
        #region Filter for my desired list

        if (item.Value is IEnumerable && item.Value.GetType().IsGenericType) //matching only for lists, I expect to work with
        {
            foreach (Dictionary<string, object> subItemListItem in item.Value as List<object>)// I am exspecting some kind of list with "KeyValuePair"'s
            {
                if (subItemListItem.ContainsKey(reducedListItem.Key))//checking for valid keys
                {
                    //doing something with "subItemListItem.Values" or "Keys" ?!
                    tempList.Add(subItemListItem[reducedListItem.Key] != null ? subItemListItem[reducedListItem.Key].ToString() : "ERROR");
                }
            }
        }

        #endregion

    }

    #endregion

    #region Adding the result to my final list

    // adding one column/record
    ergebnisListe.Add(new KeyValuePair<string, object>(reducedListItem.Key, tempList.ToArray())); //I need "string[]" first record is the heading and the rest is it's related data

    #endregion
}

除了核心列表之外,我几乎可以自由更改数据结构和类型。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

这是一个LINQ版本:

// Getting dictionaries from coreList
var dictsInCoreList =
    coreList
        .Values
        .Where(value => value is IEnumerable && value.GetType().IsGenericType)
        .SelectMany(value => value as List<object>)
        .Cast<Dictionary<string, object>>()
        .ToList();

// Generate the result
ergebnisListe =
    reducedList
        .Select(reducedListItem =>
            {
                var tempList =
                    new List<string>()
                    {
                        String.IsNullOrEmpty(reducedListItem.Value)
                            ? "!Überschrift_FEHLER"
                            : reducedListItem.Value
                    };

                tempList.AddRange(
                    dictsInCoreList
                        .Where(dict => dict.ContainsKey(reducedListItem.Key))
                        .Select(dict => dict[reducedListItem.Key]?.ToString() ?? "ERROR")
                );

                return new KeyValuePair<string, object>(reducedListItem.Key, tempList);
            }
        )
        .ToList();

由于在第一个语句中收集了所有词典,因此速度更快。

但是我觉得有些东西需要重构,因为如果coreList只包含列表(这样我们就不需要过滤.Value属性的类型了)那么它的实际类型就是Dictionary<string, List<Dictionary<string, object>>>对我来说有点味道。

但是如果没有更多关于您的解决方案的领域知识,我无法建议更好的映射。