对包含字典的对象列表进行排序

时间:2015-06-09 23:05:57

标签: c# linq sorting dictionary

这是我的目标:

row.child.show()

字典包含年份列表,月份列表。我希望按月排序 A 列表。

每个A上的字典示例:

row.child

如果我有多年,那么它可以排序如下: 2015年,2015年,2016年,2016年

我无法实现IComparable或使用任何现有的扩展方法,如OrderBy或Sort。谢谢!

2 个答案:

答案 0 :(得分:1)

我认为应该这样做:listOfA.OrderBy(a => a.Years.Min(y => y.Key + y.Value.Min() / 13d))

例如,如果字典中的最低年份和月份是2000年1月,则其值为2000 + 1/13 = 2000.0769

然后剩下的就是从每个字典中选择最小的值,然后按它排序。

注意13也可以是20,如果由于某种原因需要更好的数字,但12/x的最大部分必须是x小于1以便更适当地重视年份,因此var listOfA = new List<A> { new A { Name = "a1", Years = new Dictionary<int, List<int>> { {2015, new List<int> {3, 4, 5, 6}}, {2016, new List<int> {2, 8, 9, 10}} } }, new A { Name = "a2", Years = new Dictionary<int, List<int>> { {2013, new List<int> {3, 4, 5, 6}}, {2014, new List<int> {2, 8, 9, 10}} } }, new A { Name = "a3", Years = new Dictionary<int, List<int>> { {2015, new List<int> {3, 4, 5, 6}}, {2014, new List<int> {2, 8, 9, 10}} } }, new A { Name = "a4", Years = new Dictionary<int, List<int>> { {2014, new List<int> {1, 4, 5, 6}}, {2017, new List<int> {2, 8, 9, 10}} } } }; // listOfA is now {a1, a2, a3, a4} listOfA = listOfA.OrderBy(a => a.Years.Min(y => y.Key + y.Value.Min() / 13d)).ToList(); // listOfA is now {a2, a4, a3, a1} 必须大于12.这假设月份的范围包括1到12个。

示例I / O:

Function Close-LockedFile{
Param(
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)][String[]]$Filename
)
Begin{
    $HandleApp = 'C:\sysinternals\Handle.exe'
    If(!(Test-Path $HandleApp)){Write-Host "Handle.exe not found at $HandleApp`nPlease download it from www.sysinternals.com and save it in the afore mentioned location.";break}
}
Process{
    $HandleOut = Invoke-Expression ($HandleApp+' '+$Filename)
    $Locks = $HandleOut |?{$_ -match "(.+?)\s+pid: (\d+?)\s+type: File\s+(\w+?): (.+)\s*$"}|%{
        [PSCustomObject]@{
            'AppName' = $Matches[1]
            'PID' = $Matches[2]
            'FileHandle' = $Matches[3]
            'FilePath' = $Matches[4]
        }
    }
    ForEach($Lock in $Locks){
        Invoke-Expression ($HandleApp + " -p " + $Lock.PID + " -c " + $Lock.FileHandle + " -y") | Out-Null
    If ( ! $LastexitCode ) { "Successfully closed " + $Lock.AppName + "'s lock on " + $Lock.FilePath}
    }
}
}

答案 1 :(得分:1)

我将IComparable添加到您的A类中(当然您可以提取并作为代理传递.....)

fiddlerlink

注意:为简单起见,我假设列表已排序。否则,在您的方案中的适当位置添加您的排序:)

基本上返回不等于年或月的第一个比较。 你可以通过MyListOfAs.Sort();

来调用它
public class A:IComparable<A>
{
    public string Name { get; set; }
    public Dictionary<int, List<int>> Years { get; set; }

    private int complists(List<int> a, List<int> b)
    {
        var iret = (from i in Enumerable.Range(0, Math.Min(a.Count, b.Count))
                     where a[i].CompareTo(b[i]) != 0
                     select a[i] > b[i] ? 1 : -1).FirstOrDefault();

        return iret;
    }
    public int CompareTo(A other)
    {
        var mykeys = this.Years.Keys.ToList();
        var otherkeys = other.Years.Keys.ToList();

        var iret = (from i in Enumerable.Range(0, Math.Min(mykeys.Count, otherkeys.Count))
                     let yearDiff = mykeys[i].CompareTo(otherkeys[i])
                     let monthDiff = complists(this.Years[mykeys[0]], other.Years[otherkeys[0]])
                     where yearDiff != 0 || monthDiff != 0
                     select yearDiff != 0 ? yearDiff : monthDiff).FirstOrDefault();

        return iret != 0 ? iret : mykeys.Count > otherkeys.Count ? 1 : mykeys.Count < otherkeys.Count ? -1 : 0;
    }    }