排序列表,其对象包含两个包含数字的字符串成员

时间:2014-05-29 15:17:26

标签: c# linq

我想知道这个

的最佳解决方案

我的情况是,我从Excel工作表中获取值并将它们推送到数据库字段,有时该字段可能包含一些字符串(这就是为什么我无法使我的对象成员int / double

在我的班级中,size是负责以字节显示文件大小的变量

public class dataNameValue
{
    public string Name { get; set; }
    public string Count { get; set; }
    public string Size { get; set; }
}

我想按文件大小排序列表

List<dataNameValue> mylist = new List<dataNameValue>();
mylist = mylist.OrderByDescending(i => i.Size).ToList();

问题在于,如果我对它进行排序而不将其转换为&#34; int / double&#34;首先 - 它没有给出正确的结果

enter image description here

注意:我从数据库到该列表的所有数据都是数字

3 个答案:

答案 0 :(得分:1)

编辑: 用户定义Parse mehod以将格式错误的对象放在列表末尾的示例。

如果要按整数(大小)排序,则必须首先将字符串大小转换为整数,然后按照您的方式进行排序。

你可以: 1)忽略并删除无法提供正确大小的对象 2)如果你不能删除它们,你可以在列表的末尾(或开头)放置具有不正确的Size成员的对象。

// return MaxValue if int cannot be parsed: this will put the garbage strings t the end of the list
int Parse(string s)
{
 int result;
 if(!int.TryParse(s, out result))
   return int.MaxValue;
 return result;
 }

mylist = mylist.OrderByDescending(i => Parse(i.Size)).ToList();

答案 1 :(得分:1)

如果你有值单位(百分比)形式的大小,那么我会使用Size类而不是字符串:

public class Size
{
    public static Size Parse(string s)
    {
        Regex regex = new Regex(@"(?<value>\d+(\.\d+)?)\s*(?<units>\w+)\s*.*");
        var match = regex.Match(s);
        if (!match.Success)
            throw new ArgumentException("Unknown size format");

        return new Size {
            Value = Double.Parse(match.Groups["value"].Value),
            Units = GetSizeUnits(match.Groups["units"].Value)
        };
    }

    private static SizeUnit GetSizeUnits(string units)
    {
        switch (units.ToUpper())
        {      
            // sorry don't know how you define bytes in your system
            case "KB": return SizeUnit.Kilobyte;
            case "MB": return SizeUnit.Megabyte;
            case "GB": return SizeUnit.Gigabyte;
            case "TB": return SizeUnit.Terabyte;
            default: throw new ArgumentException("Unknown size units");
        }
    }

    public double Value { get; private set; }
    public SizeUnit Units { get; private set; }
    public double ValueInBytes
    {
        get { return Math.Pow(1024, (int)Units) * Value; }
    }
}

它可以简单地将诸如"5.66 GB (7.75%)"之类的字符串解析为具有适当单位的大小对象,并以字节为单位计算值。 E.g。

var size = Size.Parse("240.5 MB (0.4%)");

enter image description here

单位是简单的枚举

public enum SizeUnit
{
    Byte,
    Kilobyte,
    Megabyte,
    Gigabyte,
    Terabyte
}

使用此类型而不是字符串,您可以非常轻松地对数据列表进行排序

mylist = mylist.OrderByDescending(d => d.Size.ValueInBytes).ToList();

答案 2 :(得分:0)

创建此类

public class dataNameValueComparer : IComparer<dataNameValue>
{
    public int Compare(dataNameValue x, dataNameValue y)
    {
        //Here process your comparation
        //return  <0 if x<y 
        // 0 if x=y 
        // >0 if x>y
        //This sample return the default string compration
        return string.Compare(x.Size, y.Size);
    }
}

然后使用它进行排序

mylist = mylist.OrderByDescending(i => i,new dataNameValueComparer() ).ToList();

您可以根据需要创建各种类进行比较。 像

public class SizeComparer : IComparer<string>
    {
        public int Compare(string x, string y)
        {
            //Here process your comparation
            //return  <0 if x<y 
            // 0 if x=y 
            // >0 if x>y
            //This sample return the default string compration
            return string.Compare(x, y);
        }
    }

使用原始调用添加比较器参数

   mylist = mylist.OrderByDescending(i => i.Size,new SizeComparer() ).ToList();

在比较器中,您可以进行任何尺寸转换