过滤所有仅与输入字符串数组或任意数字匹配的字典元素
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
总体思路:
- 使用“.”拆分键进入数组
- 确保 subStringArray 是步骤 1 中数组的子集
- 确保步骤 2 中成功子集匹配的任何剩余元素都是数字
- 形成最终结果
更新(基于评论)
为了确保即使输入数组大于字典键长度也能获得结果,例如("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"。
我有一个字典,它有一个扁平化的键值对,还有一个字符串数组。我只想获取字典元素,如果拆分,其键应仅包含输入数组中指定的字符串或任何数值。
目的是从扁平对象中读取 属性 的值列表。
示例字典:
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
总体思路:
- 使用“.”拆分键进入数组
- 确保 subStringArray 是步骤 1 中数组的子集
- 确保步骤 2 中成功子集匹配的任何剩余元素都是数字
- 形成最终结果
更新(基于评论)
为了确保即使输入数组大于字典键长度也能获得结果,例如("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"。