我有数据结构
-Emp1 - Emp1_1 - Emp1_1_1
- Emp1_1_2
- Emp1_2 - Emp1_2_1
- Emp1_2_2
-Emp2 - Emp2_1 - Emp2_1_1
- Emp2_1_2
- Emp2_2 - Emp2_2_1
- Emp2_2_2
我想要一个字典,它将极端叶节点作为键,其最高父节点作为值。 OP:
(Emp1_1_1,Emp1) (Emp1_1_2,Emp1) (Emp1_2_1,Emp1) (Emp1_2_2,Emp1) (Emp2_1_1,Emp2) (Emp2_1_2,Emp2) (Emp2_2_1,Emp2) (Emp2_2_2,Emp2)
(Emp1_1_1, Emp1)
(Emp1_1_2, Emp1)
(Emp1_2_1, Emp1)
(Emp1_2_2, Emp1)
(Emp2_1_1, Emp2)
(Emp2_1_2, Emp2)
(Emp2_2_1, Emp2)
(Emp2_2_2, Emp2)
下面是c#代码
public class Program
{
public static void Main()
{
var program = new Program();
var empList = program.GetData();
//Some linq which return the expected dictionary.
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int parentEmployee { get; set; }
public List<Employee> childList { get; set; }
}
List<Employee> GetData()
{
var empList = new List<Employee>();
var emp1 = new Employee() { Id = 1, Name = "Emp1_Name", childList = new List<Employee>() };
var emp1_1 = new Employee() { Id = 2, Name = "Emp1_1_Name", parentEmployee = emp1.Id, childList = new List<Employee>() };
var emp1_2 = new Employee() { Id = 3, Name = "Emp1_2_Name", parentEmployee = emp1.Id, childList = new List<Employee>() };
emp1.childList.Add(emp1_1);
emp1.childList.Add(emp1_2);
var emp1_1_1 = new Employee() { Id = 4, Name = "Emp1_1_1_Name", parentEmployee = emp1_1.Id };
var emp1_1_2 = new Employee() { Id = 5, Name = "Emp1_1_2_Name", parentEmployee = emp1_1.Id };
emp1_1.childList.Add(emp1_1_1);
emp1_1.childList.Add(emp1_1_2);
var emp1_2_1 = new Employee() { Id = 6, Name = "Emp1_2_1_Name", parentEmployee = emp1_2.Id };
var emp1_2_2 = new Employee() { Id = 7, Name = "Emp1_2_2_Name", parentEmployee = emp1_2.Id };
emp1_2.childList.Add(emp1_2_1);
emp1_2.childList.Add(emp1_2_2);
var emp2 = new Employee() { Id = 1, Name = "emp2_Name", childList = new List<Employee>() };
var emp2_1 = new Employee() { Id = 2, Name = "emp2_1_Name", parentEmployee = emp2.Id, childList = new List<Employee>() };
var emp2_2 = new Employee() { Id = 3, Name = "emp2_2_Name", parentEmployee = emp2.Id, childList = new List<Employee>() };
emp2.childList.Add(emp2_1);
emp2.childList.Add(emp2_2);
var emp2_1_1 = new Employee() { Id = 4, Name = "emp2_1_1_Name", parentEmployee = emp2_1.Id };
var emp2_1_2 = new Employee() { Id = 5, Name = "emp2_1_2_Name", parentEmployee = emp2_1.Id };
emp2_1.childList.Add(emp2_1_1);
emp2_1.childList.Add(emp2_1_2);
var emp2_2_1 = new Employee() { Id = 6, Name = "emp2_2_1_Name", parentEmployee = emp2_2.Id };
var emp2_2_2 = new Employee() { Id = 7, Name = "emp2_2_2_Name", parentEmployee = emp2_2.Id };
emp2_2.childList.Add(emp2_2_1);
emp2_2.childList.Add(emp2_2_2);
empList.Add(emp1);
empList.Add(emp2);
return empList;
}
}
我尝试了一些解决方案,比如在linq中调用私有自引用功能, 但它适用于一个父母 - 一个孩子的关系。
答案 0 :(得分:1)
如果可以使用递归函数:
Func<IEnumerable<Employee>, IEnumerable<Employee>> flatten = null;
flatten = (IEnumerable<Employee> employees) =>
employees.SelectMany(c => c.childList != null ? flatten(c.childList) : Enumerable.Empty<Employee>()).Concat(employees);
var dict = (
from topNode in empList
from node in flatten(topNode.childList)
where node.childList == null || node.childList.Count == 0
select new KeyValuePair<string, string>(node.Name, topNode.Name)
).ToDictionary(kv => kv.Key, kv => kv.Value);
foreach(var keyValuePair in dict)
{
Console.WriteLine($"Key={keyValuePair.Key}, Value={keyValuePair.Value}");
}
输出:
Key=Emp1_1_1_Name, Value=Emp1_Name
Key=Emp1_1_2_Name, Value=Emp1_Name
Key=Emp1_2_1_Name, Value=Emp1_Name
Key=Emp1_2_2_Name, Value=Emp1_Name
Key=emp2_1_1_Name, Value=emp2_Name
Key=emp2_1_2_Name, Value=emp2_Name
Key=emp2_2_1_Name, Value=emp2_Name
Key=emp2_2_2_Name, Value=emp2_Name
答案 1 :(得分:0)
试试这个
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="a2msoft.app_one">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".AppController"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".activiy.LoginActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activiy.RegisterActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".activiy.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/AppTheme"
>
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchResultsActivity" />
</activity>
<activity
android:name=".activiy.ItemActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:parentActivityName=".activiy.MainActivity"
/>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activiy.MainActivity" />
</application>
</manifest>
结果
public static void Main()
{
var program = new Program();
var empList = program.GetData();
Func<IEnumerable<Employee>, Employee, Dictionary<Employee, Employee>> TreeToDict = null;
TreeToDict = (employees, topParent) =>
employees.SelectMany(e =>
{
if(e.childList != null)
{
return TreeToDict(e.childList, topParent == null ? e : topParent);
}
else
{
Dictionary<Employee, Employee> dict = new Dictionary<Employee, Employee>();
dict.Add(e, topParent == null ? e : topParent);
return dict;
}
}).ToDictionary(x => x.Key, x => x.Value);
foreach(var emp in TreeToDict (empList, null))
{
Console.WriteLine("key : {0}, value {1}", emp.Key.Name, emp.Value.Name);
}
}