代码之家  ›  专栏  ›  技术社区  ›  user8512043

根据每个元素中的数字对列表进行排序

  •  1
  • user8512043  · 技术社区  · 3 年前

    几天前我试图解决一个问题,在他的帮助下几乎解决了 . 不幸的是,我陷入了无法解决的境地。以下是场景:

    输入 :

    [7, "aaa", "a", "cccccccccc", 5]
    

    输出 :

    ["a", "aaa", 5, 7, "cccccccccc"]
    

    因此,您可以看到,根据元素中字母的数量,应该对数组进行排序。对于数字,也应进行排序。以下代码曾一度奏效:

    //Dynamic list where we can have string and integers
    List<dynamic> aLst = new List<dynamic>();
    aLst.Add(7);
    aLst.Add("aaa");
    aLst.Add("aa");
    aLst.Add("cccc");
    aLst.Add("a");
    aLst.Add(2);
    aLst.Add(5);
    aLst.Add("cccccc");
    
    int val;
         
    //What I did here, converted all items into string
         
    //Checks if the list contains string   
    var letters = aLst.Where(i => !int.TryParse(i.ToString(), out val)).OrderBy(i => i.Length).ToList();
        
    //Checks if the list contains number
    var numbers = aLst.Where(i => int.TryParse(i.ToString(), out val)).OrderBy(i => int.Parse(i.ToString())).ToList();
    
    //Finally from the number result set, taking the numbers to get their indexes and set them into the list accordingly
    foreach (var number in numbers)
    {
       //Checks number index
       var index = int.Parse(number.ToString());
    
       if (letters.Count() >= index)
       {
          letters.Insert(index, number); //Assign index to numbers
       }
       else
       {
          letters.Insert(number);
       }
    }
    
    foreach(var value in letters)
    {
           Console.WriteLine(value);
    } 
    

    上面的代码得到了预期的结果。但当输入如下时,它返回不同的结果集,我无法相应地设置:

     List<dynamic> aLst = new List<dynamic>();
     aLst.Add(7);
     aLst.Add("aaa");
     aLst.Add("aa");
     aLst.Add("cccc");
     aLst.Add("a");
     aLst.Add(2);
     aLst.Add(10);
     aLst.Add(5);
     aLst.Add("cccccc");
     aLst.Add("cccccccccccc");
    

    ["a", 2, "aa", "aaa", 5, "cccc", 7, "cccccc", "cccccccccccc", 10]
    

    预期输出 :

     ["a", 2, "aa", "aaa", "cccc", 5, "cccccc", 7, 10, "cccccccccccc"]
    

    我在这里做错了什么或错过了什么?如果您有任何想法,我们将不胜感激。

    代码段 : Sort Array Elements

    2 回复  |  直到 3 年前
        1
  •  3
  •   Lzh    3 年前

    这里的关键是检查对象的类型。如果是字符串,则使用该字符串的长度作为顺序,否则假设它是一个 int 并将值本身用于订单。

    如果对象列表中还有其他内容,例如某个随机类的实例,则会引发异常。

    var list = new List<object> { 7, "aaa", "a", "cccccccccc", 5 };
    
    // this assumes the elements in the array above (which can be anything) are only strings or integer
    var ordered = list.OrderBy(x => x is string str ? str.Length : (int)x).ToList();
    
    // print array to see results
    Console.WriteLine(string.Join(",", ordered));
    
        2
  •  2
  •   Anu Viswan    3 年前

    我希望我正确理解了你的分类意图。您可以使用自定义比较器来隔离比较逻辑,比较逻辑可以检查它是字符串还是数字。例如

    public class Comparer : IComparer<object>
    {
        public int Compare(object a, object b)
        {
            var valA = GetValue(a);
            var valB = GetValue(b);
            
            return valA.CompareTo(valB);
        }
        
        private int GetValue(object ch)
        {
            if(Int32.TryParse(ch.ToString(),out var val))
                return val;
            else
                return ch.ToString().Length;
        }
        
    }
    

    现在,您可以轻松地将自定义比较器与Linq结合使用。

    var output = list.OrderBy(x=>x, new Comparer())
    

        3
  •  0
  •   Technorg    3 年前
    List<dynamic> aLst = new List<dynamic>();
    aLst.Add(7);
    aLst.Add("aaa");
    aLst.Add("aa");
    aLst.Add("cccc");
    aLst.Add("a");
    aLst.Add(2);
    aLst.Add(5);
    aLst.Add("cccccc");
    
    for (int i = 0; i < aLst.Count; i++)
    {
        if (aLst[i] is int val)
        {        
            aLst.RemoveAt(i);
            aLst.Insert(0, val);
        }
    }
    
    //var ty = aLst.Select(x => x.ToString());
    var ordered = aLst.OrderBy(x => x is string str ? str.Length : (int)x).ToList();
    Console.WriteLine(string.Join(",", ordered)); //a,2,aa,aaa,cccc,5,cccccc,7