【问题标题】:How to order obj based on their hierachy?如何根据层次结构对 obj 进行排序?
【发布时间】:2018-04-19 10:31:48
【问题描述】:

给定 2 个对象 PeopleRelation

public class People
{   
    public int id ;
    public string externalId;
    public PostalInfo postalInformation;
}

public class Relation
{        
    public int id ;
    public int type ;
    public string sourceExternalId ;
    public string destExternalId ;
}

People 存储有关某人的信息的位置。
Relation存储2个People之间的连接。

如何根据人们的等级对他们进行排序,从“最老的”(更深的)到不太重要的?

我所说的较旧,是指与其他元素绑定较少的元素。因此,当我订购时,我可以验证和创建这些元素而不会丢失参考。但由于验证是由人工完成的,我不能等待所有这些都被验证一次就提交一次。

var peoplesAwaitingValidation =
    new List<People> {
        new People{ id = 1 , externalId = "A" },
        new People{ id = 2 , externalId = "B" },
        new People{ id = 3 , externalId = "C" },
        new People{ id = 4 , externalId = "D" },
        new People{ id = 5 , externalId = "E" },
        new People{ id = 6 , externalId = "F" },
    };

var relationsAwaitingValidation =
    new List<Relation> {
        new Relation{ id = 1 , sourceExternalId = "A", destExternalId = "B" },
        new Relation{ id = 2 , sourceExternalId = "A", destExternalId = "C" },
        new Relation{ id = 3 , sourceExternalId = "A", destExternalId = "D" },
        new Relation{ id = 4 , sourceExternalId = "E", destExternalId = "A" },
        new Relation{ id = 3 , sourceExternalId = "E", destExternalId = "B" }
    };

//Expected result :
var orderedPeoplesAwaitingValidation = new List<People> {
                                                    // Weight
        new People{ id = 6 , externalId = "F" },    // 0 
        new People{ id = 5 , externalId = "E" },    // 1
        new People{ id = 1 , externalId = "A" },    // 2 
        new People{ id = 3 , externalId = "C" },    // 3
        new People{ id = 4 , externalId = "D" },    // 3
        new People{ id = 2 , externalId = "B" },    // 5
    };

我想到的图形表示:

1        2        3   // <==  Weight
E  --->  A  --->  B
            --->  C
            --->  D
   --->  B

F==0

mcve and attempt

【问题讨论】:

  • 我没有看到“年长”或“体重”的明确定义。能具体点吗?
  • 如果“B”与“E”有关系呢?关于/反对周期的任何规则?
  • 所以重量是累积的? B 有5 因为E ---&gt; A ---&gt; B = 3 加上E ---&gt; B = 2 ?
  • 抱歉迟到了,@HenkHolterman,不!没有他们之前过滤过的圈子参考。
  • @MongZhu,是的,不是的。是的,在解决方案的这种心理表征中,权重是累积的,但最大权重似乎是更好的解决方案。这只是我面临这个问题的一个简单愿景。因为所以需要一个 mcve 我添加了它。但它可能会导致某人有另一种/更好的方式来做这件事。目的是要有一个订购者列表,这样在创建时我们就不会缺少参考。

标签: c# linq


【解决方案1】:

您应该对关系进行多次迭代,以找到从我们知道权重的点开始的新关系。

Dictionary<string, int> weights = peoplesAwaitingValidation
    .Where(x => relationsAwaitingValidation
        .Count(o => o.destExternalId == x.externalId) == 0)
    .ToDictionary(o => o.externalId, o => 0);
int processed = 0;
while (processed < relationsAwaitingValidation.Count - 1)
    foreach (Relation r in relationsAwaitingValidation)
        if (weights.ContainsKey(r.sourceExternalId) &&
           !weights.ContainsKey(r.destExternalId))
        {
            weights.Add(r.destExternalId, weights[r.sourceExternalId] + 1);
            processed++;
        }

注意:此代码假定始终存在至少一个与它没有联系的根人物。

【讨论】:

  • 这个计数从 0 开始,要从 1 开始,只需更改 .ToDictionary 调用中的 0
  • 它工作正常!谢谢。我通常会等待几天才能验证答案。我可以将第一行代码格式化成多行,这样在没有水平滚动的情况下更具可读性。
  • 不确定,但也许.Where(...).Count() 可以重写.Count(...)(与使用.First(...) 代替.Where(...).First() 相同的方式) - 请参阅msdn Queryable.Count
  • @H.J.Meijer 他写道“我通常会等待几天才能验证答案”,所以他会的,别担心 :)(除非出现更好的解决方案猜)
  • 看到没有忘记你。我总是在周末回顾我所有的行动评论、投票、回答问题。如果他们足够老了^^
猜你喜欢
  • 2022-01-08
  • 2020-12-25
  • 2016-03-06
  • 1970-01-01
  • 2019-12-27
  • 2013-09-16
  • 2017-07-06
  • 2016-05-21
  • 2013-01-13
相关资源
最近更新 更多