【问题标题】:Organize Values in Dictionary alphabetically按字母顺序组织字典中的值
【发布时间】:2016-05-12 16:45:13
【问题描述】:

大家好,我一直在阅读许多与我想做的问题类似的帖子,但不幸的是,其中任何一个都与我的问题相符。实际上我有用于填充下拉列表的字典,因为字典中的值无法按字母顺序组织(不一致,您将在下面的代码中看到值)我如何例如创建数组或列表使用序列号,按此 ID 对值进行排序,然后将组织后的值放入新字典中......或任何其他方式。感谢您的快速帮助。

这实际上是我的代码:

    public static Dictionary<string, string> GetDocumentTypes()
    {            

        Dictionary<string, string> docTypeList = new Dictionary<string, string>();

        //Values inserted manually for the moment
        docTypeList.Add(Guid.NewGuid().ToString(), "F17- MyValue17");
        docTypeList.Add(Guid.NewGuid().ToString(), "F19- MyValue19");
        docTypeList.Add(Guid.NewGuid().ToString(), "F20- MyValue20");
        docTypeList.Add(Guid.NewGuid().ToString(), "F21- MyValue21");
        docTypeList.Add(Guid.NewGuid().ToString(), "F2- MyValue2");
        docTypeList.Add(Guid.NewGuid().ToString(), "F1- MyValue1");
        docTypeList.Add(Guid.NewGuid().ToString(), "F3- MyValue3");
        docTypeList.Add(Guid.NewGuid().ToString(), "F4- MyValue4");

        return docTypeList;
    }

//这里我尝试用这些值“有序”填充下拉列表

字典 doctypesource = GetDocumentTypes();

        var ordered = doctypesource.OrderBy(x => x.Value);

        DocumentType.DataSource = ordered;
        DocumentType.DataValueField = "Key";
        DocumentType.DataTextField = "Value";
        DocumentType.DataBind();
        DocumentType.Items.Insert(0, new ListItem());

最后,当填充下拉列表时,值没有排序,但它们得到的顺序如下:F1- MyValue1, F17- MyValue17, F19- MyValue19, F2- MyValue2, F20- MyValue20, F21- MyValue21, F3- MyValue3 , F4- MyValue4;

所以我想要这样的顺序:F1- MyValue1, F2- MyValue2, F3- MyValue3, F4- MyValue4, F17- MyValue17, F19- MyValue19, F20- MyValue20, F21- MyValue21

【问题讨论】:

    标签: c# asp.net arrays list dictionary


    【解决方案1】:

    这些值是字符串,因此它们按字母数字排序。因此,“F17-MyValue17”出现在“F2-MyValue2”之前是正确的,因为第二个字符在第一个值中是 1,在第二个值中是 2。

    如果您能够用前导零填充您的值,则排序将起作用。因此,例如,您将使用以下内容

        docTypeList.Add(Guid.NewGuid().ToString(), "F17- MyValue17");
        docTypeList.Add(Guid.NewGuid().ToString(), "F19- MyValue19");
        docTypeList.Add(Guid.NewGuid().ToString(), "F20- MyValue20");
        docTypeList.Add(Guid.NewGuid().ToString(), "F21- MyValue21");
        docTypeList.Add(Guid.NewGuid().ToString(), "F02- MyValue02");
        docTypeList.Add(Guid.NewGuid().ToString(), "F01- MyValue01");
        docTypeList.Add(Guid.NewGuid().ToString(), "F03- MyValue03");
        docTypeList.Add(Guid.NewGuid().ToString(), "F04- MyValue04");
    

    如果您不能这样做,则需要提取字符串的数字部分以用于排序。你如何做取决于你如何获得这些文本值。

    以下内容将在您的示例代码中使用您拥有的值格式

    var ordered = docTypeList.OrderBy(x => int.Parse(new string(x.Value.SkipWhile(c => !char.IsNumber(c)).TakeWhile(char.IsNumber).ToArray())));
    

    这是另一种可能的解决方案,它首先按字符串的第一部分 alpha 进行排序,然后根据第一个数字部分(如果有的话)进行排序。同样,它适用于您在评论中提供的示例值,但可能不适用于您想要排序的每个值。例如,如果您有“F1-A”和“F1-B”,它将按 F 排序,然后按 1,但它会忽略字符串的其余部分,因此如果在首先是字典。

            docTypeList.Add(Guid.NewGuid().ToString(), "C");
            docTypeList.Add(Guid.NewGuid().ToString(), "F17");
            docTypeList.Add(Guid.NewGuid().ToString(), "F1");
            docTypeList.Add(Guid.NewGuid().ToString(), "B");
            docTypeList.Add(Guid.NewGuid().ToString(), "F");
            docTypeList.Add(Guid.NewGuid().ToString(), "F2");
            docTypeList.Add(Guid.NewGuid().ToString(), "Z");
            docTypeList.Add(Guid.NewGuid().ToString(), "F20");
            docTypeList.Add(Guid.NewGuid().ToString(), "X");
            docTypeList.Add(Guid.NewGuid().ToString(), "A");
            docTypeList.Add(Guid.NewGuid().ToString(), "Y");
    
            var ordered = docTypeList.OrderBy(x => new string(x.Value.TakeWhile(c => !char.IsDigit(c)).ToArray()))
                .ThenBy(x => int.Parse(
                    x.Value.Any(char.IsDigit) ? new string(x.Value.SkipWhile(c => !char.IsDigit(c)).TakeWhile(char.IsDigit).ToArray()) : "0"
                    ));
    

    【讨论】:

    • 谢谢 +Marc,这可能是解决问题的好方法,但是在上面的示例中,我只指定了“Fs”值,但我也有“其他元素名称 1”、“其他元素名称 2”之类的值" 等等,这个解决方案会避免以字母开头的项目,所以订单会再次变坏......这是正确的还是我错了?
    • 解决方案基于您提供的值以及您期望对值进行排序的方式。如果您尝试将“F17-MyValue17”与“F01-MyValue01”和“其他元素名称1”进行排序,那么您希望该顺序是什么顺序?元素的排序方式需要有一些一致的格式或规则。
    • 我建议的解决方案是获取字符串中找到的第一个数字并使用它进行数字排序。数字可以位于字符串的开头、字符串的中间或结尾。它只是跳过所有非数字字符(如果有的话)然后抓取每个数字字符,直到它到达另一个非数字字符或字符串的末尾。
    • 是的,马克,正如我所说,您的解决方案很好,而且我也知道您的答案是基于我的第一个示例,我只是想问当我添加我真正拥有的所有值时会发生什么,我做到了其余的就不提了,因为它们很容易组织,因为它们是没有数字的字符串,例如“Aelement a”、“Belement b”、“Celement C”等等。我正在做的是提取以“F#”开头的值,并在像 01、02、03 这样的单个数字时添加一个零。虽然这是一种很难做到的方法,但它工作得很好。再次感谢您。
    • 结果列表将如下所示:A、B、C、F、F01、F02、F17、F20、X、Y、Z。假设用逗号分隔的每个字母或元素是列表。
    【解决方案2】:

    将 IComparer 传递给 OrderBy,考虑到您的数字在 F 后有 2 位数字,下面是答案,您可以对所有情况进行适当的修改

    class ComparerStrings : IComparer<string>
    {
        public int Compare(string x, string y)
        {
            //Compare by numbers after your initial F
            return int.Parse(x.Substring(1, 2)).CompareTo(y.Substring(1, 2));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 1970-01-01
      • 2019-12-24
      • 1970-01-01
      • 2014-01-26
      • 1970-01-01
      相关资源
      最近更新 更多