过滤所有仅与输入字符串数组或任意数字匹配的字典元素

Filter all the Dictionary elements which are matching with the input string array only or any number

我有一个字典,它有一个扁平化的键值对,还有一个字符串数组。我只想获取字典元素,如果拆分,其键应仅包含输入数组中指定的字符串或任何数值。

目的是从扁平对象中读取 属性 的值列表。

示例字典:

Key: "Owner.0.Alias", Value: "Jo"
Key: "Owner.0.Name", Value: "John"
Key: "Owner.0.ReportsTo.Alias", Value: "Sam"
Key: "Owner.0.ReportsTo.Name", Value: "Samantha"    
Key: "Owner.1.Alias", Value: "Ma"
Key: "Owner.1.Name", Value: "Mary"
Key: "Owner.1.ReportsTo.Alias", Value: "Geo"
Key: "Owner.1.ReportsTo.Name", Value: "George"    
Key: "Manager.Alias", Value:"Ke"
Key: "Manager.Name", Value:"Ken"

输入数组 -

string str = Owners.Alias;
var subStringArr = str.Split('.');

**Input array will have** : [0]: Owners, [1]:Alias

我想从上面的列表中过滤掉所有包含关键字 "Owners"/"Alias"/"Number" 的字典元素。

**Expected output: **
Key: Owner.0.Alias, Value: Jo
Key: Owner.1.Alias, Value: Ma

请注意:字典键的层级可以任意长。级别未知。

我尝试了几种使用 join/intercept/contains 过滤字典的方法。我遇到的问题是,过滤后的字典还会有一些额外的关键字(如 reportsTo),然后是输入字符串数组。

您可以执行以下操作。为了便于阅读,我将查询拆分为子查询。

var intial = dictionary.Keys.Select(c=> c.Split('.'));
var intermediate = intial.Where(x=>x
                            .Except(subStringArr)
                            .All(c=>Regex.IsMatch(c, @"^\d+$")));

var result =  intermediate.Select(x=> new KeyValuePair<string,string>(string.Join(".",x), dictionary[string.Join(".",x)]))
                        .ToDictionary(x=>x.Key, y=>y.Value);

输入

var dictionary = new Dictionary<string,string>{
["Owner.0.Alias"] = "Jo",
["Owner.0.Name"] = "John",
["Owner.0.ReportsTo.Alias"] = "Sam",
["Owner.0.ReportsTo.Name"] = "Samantha",
["Owner.1.Alias"] = "Ma",
["Owner.1.Name"] = "Mary",
["Owner.1.ReportsTo.Alias"] = "Geo",
["Owner.1.ReportsTo.Name"] = "George",
["Manager.Alias"] = "Ke",
["Manager.Name"] = "Ken",
};

string str = "Owner.Alias";
var subStringArr = str.Split('.');

你会得到输出

Key: Owner.0.Alias, Value: Jo
Key: Owner.1.Alias, Value: Ma

总体思路:

  1. 使用“.”拆分键进入数组
  2. 确保 subStringArray 是步骤 1 中数组的子集
  3. 确保步骤 2 中成功子集匹配的任何剩余元素都是数字
  4. 形成最终结果

更新(基于评论)

为了确保即使输入数组大于字典键长度也能获得结果,例如("Persona.Requestor.Owner.ReportsTo.Name"),您可以将中间查询更改为

var intermediate = intial.Where(x=>  (subStringArr.Count() > x.Count()?
                                            subStringArr.Except(x)
                                           :x.Except(subStringArr))
                            .All(c=>Regex.IsMatch(c, @"^\d+$")));

这将有助于将键解析为 "Persona.0.Requestor.0.Owner.0.ReportsTo.Name"。