我有一个'任务列表'执行任务被授予'当一个人结束时#39;任务不是按顺序存储的,所以我试图找到两件事。
class quests
{
public string questGrantID { get; set; }
public string questEndID { get; set; }
}
实施例
+--------------+--------------+ | grants | ends | +--------------+--------------+ | quest234 | quest567 | | quest987 | quest234 | | quest654 | quest987 | +--------------+--------------+
家长任务:在这个例子中,我会知道父母的问题。任务是 quest567 ,因为父项位于questEndID下,但不在questGrantID下。
儿童任务:在此示例中, quest567 完成后,用户被授予 quest234 即可。当任务 quest234 结束时, quest987 被授予,依此类推。
我不知道从哪里开始,我已经查找了加入两个单独列表的示例,而不是相同。我假设这将是两个不同的功能,一个是找到父母,另一个找到孩子。从那里我将创建一个新列表。
实施例
+--------------+--------------+ | order | quest | +--------------+--------------+ | 1 | quest567 | | 2 | quest234 | | 3 | quest987 | | 4 | quest654 | +--------------+--------------+
答案 0 :(得分:0)
查找父任务非常简单,只需获取不在任何Grant中的ID列表。
使用方便的扩展方法:
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source) => new HashSet<T>(source);
您可以收集所有GrantID并找到不存在的EndID:
var grants = questsList.Select(q => q.questGrantID).ToHashSet();
var parents = questsList.Select(q => q.questEndID).Where(q => !grants.Contains(q));
既然你的链是递归的,你需要一个循环来跟随链。编写另一种扩展方法,从起点生成任务链:
public static IEnumerable<string> questChain(this List<quests> allQuests, string curQuestID) {
yield return curQuestID;
var nextQuest = allQuests.ToDictionary(q => q.questEndID, q => q.questGrantID);
for (; nextQuest.TryGetValue(curQuestID, out var nextQuestID); curQuestID = nextQuestID)
yield return nextQuestID;
}
现在你可以在所有父母身上调用它来获得所有链条:
var questChains = parents.Select(pq => questsList.questChain(pq));
现在如果你真的想要订单,任务对,你可以为每个链编号:
var orderedQuests = questChains.Select(qc => qc.Select((quest, i) => new { order = i+1, quest } ));
如果您希望编号在链中保持连续,则需要在查询之外跟踪编号:
var curOrder = 1;
var orderedQuestsContinuous = questChains.Select(qc => qc.Select(quest => new { order = curOrder++, quest }));