2010-02-23 46 views
1

我有的列表是基于检查前4个值进行正确排序,但我需要列表中未预定义的任何其他值(并且不以CS开头)正如我在下面评论的那样优先考虑。非预定义的值可能总是以数值开头的任何东西,所以任何以1-9(1,2,3,4,5,6,7,8,9)开头的东西。C#:自定义顺序数组,扭曲:

我该如何自定义类似这样的东西?我是否应该专注于在单独的列表中重新定义以1-9开头的任何内容,或者有什么我可以使用的将代表“任何未定义的内容都在这里”谢谢!

更新:感谢您的帮助每个人,我称它为一个夜晚,并用Excel生成每个数字组合从0-9999开始00000001等以及000-,001-为3位数字去在古怪的CS#之前。很酷的是,该程序需要一两秒钟的时间来处理所有的事情,这看起来好像在做很多工作! (我想是的)我可以添加一个进度条!程序现在是229kb,但它的工作原理!有时你只需打破胶带。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 


namespace WindowsFormsApplication1 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    public class Comparer : IComparer<string> 
    { 

     private Dictionary<string, int> _order; 

     public Comparer() 
     { 
      List<string> list = new List<string>() 
    { 
     "CS01", 
     "CS10", 
     "CS58", 
     "CS11", 
     "CS71", 
     "CS02", 
     "CS55", 
     "CS03", 
     "CS70", 
     "CS54", 
     "CS60", 
      //<---How to prioritize any value that is not predefined in list to show up here? such as 1234-444-555 
     "CS57", 

    }; 

      _order = new Dictionary<string, int>(); 
      for (int i = 0; i < list.Count; i++) 
      { 
       _order.Add(list[i], i); 
      } 
     } 

     public int Compare(string x, string y) 
     { 
      if (x.Length < 4 || y.Length < 4) 
       return x.CompareTo(y); 

      string xPrefix = x.Substring(0, 4); 
      string yPrefix = y.Substring(0, 4); 

      int xSequence; 
      int ySequence; 
      if (_order.TryGetValue(xPrefix, out xSequence) 
       && _order.TryGetValue(yPrefix, out ySequence)) 
      { 
       return xSequence.CompareTo(ySequence); 
      } 
      else 
      { 
       return x.CompareTo(y); 
      } 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 

     textBox1.Text = textBox1.Text.Replace("(", ""); 
     textBox1.Text = textBox1.Text.Replace(")", ""); 
     string[] items = textBox1.Text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 
     Array.Sort<string>(items, 0, items.Length, new Comparer()); 
     textBox2.Text = String.Join(Environment.NewLine, items); 

     } 



} 

}

+0

您是否在寻找“自然排序”?有关讨论,请参阅http://www.codinghorror.com/blog/2007/12/sorting-for-humans-natural-sort-order.html。 – 2010-02-23 13:51:07

回答

1

您可以使用LINQ。但是,这假设你的所有字符串都有CS,其余都是数字。

List<string> list = new List<string>(); 

list.Add("CS01"); 
list.Add("CS02"); 
list.Add("CS03"); 
list.Add("CS14"); 
list.Add("CS11"); 
list.Add("CS5"); 
list.Add("CS17"); 

List<string> orderList = list 
    .OrderBy<string, int>(i => int.Parse(i.Replace("CS", string.Empty))) 
    .ToList<string>(); 

// Print List 
for (int i = 0; i < orderList.Count; i++) 
{ 
    Console.WriteLine(orderList[i]); 
} 

打印

CS01 
CS02 
CS03 
CS5 
CS11 
CS14 
CS17 

如果你的字符串比较复杂我会创造另一个函数以帮助解析。在这种情况下,这是简单的示例代码,而不是解析给定字符串中数字的理想方法。例如,如果你的字符串是CSS101,它会抛出异常,因为它不能将S101解析为int。我会把这些留给你来补充。

+0

阅读你的答案,我不认为它回答了这个问题 - 你认为你所有的字符串都有CS,并且圣洁提到他正在寻找识别不以**开头的字符串。 – CrimsonX 2010-02-23 14:50:54

+0

我编辑了我的问题,以帮助澄清大卫当时是否正确,这是我的错。假设CS是唯一的字符串,则为 – Saintjah 2010-02-23 14:58:59

+0

+1。 – 2010-02-23 15:00:36

1

您可以创建一个小的自定义类,它实现IComparer为您排序。您返回-1表示第一个参数小于第二个参数,1表示较大,0表示相等。

0

你当然可以改进这个解决方案,但我相信它实现了IComparer尼克提到。

public class Comparer : IComparer<string> 
    { 

     private Dictionary<string, int> _order; 

     public Comparer() 
     { 
     List<string> list = new List<string>() 
     { 
      "CS01", 
      "CS10", 
      "CS58", 
      "CS11", 
      "CS71", 
      "CS02", 
      "CS55", 
      "CS03", 
      "CS70", 
      "CS54", 
      "CS60", 
       //<---How to prioritize any value that is not predefined in list to show up here? such as 1234-444-555 
      "CS57", 

     }; 

     _order = new Dictionary<string, int>(); 
     for (int i = 0; i < list.Count; i++) 
     { 
      _order.Add(list[i], i); 
     } 
     } 

     public int Compare(string x, string y) 
     { 
     //If either string is less than 4 characters, return the comparsion of the two strings 
     if (x.Length < 4 || y.Length < 4) 
      return x.CompareTo(y); 

     string xPrefix = x.Substring(0, 4); 
     string yPrefix = y.Substring(0, 4); 

     int xSequence; 
     int ySequence; 
     if (_order.TryGetValue(xPrefix, out xSequence) 
      && _order.TryGetValue(yPrefix, out ySequence)) 
     { 
      // If both X and Y are in dictionary, return the comparison of the two 
      return xSequence.CompareTo(ySequence); 
     } 

     if (_order.TryGetValue(xPrefix, out xSequence)) 
     { 
      // If only X is in dictionary, x > y 
      return 1; 
     } 

     if (_order.TryGetValue(yPrefix, out ySequence)) 
     { 
      // If only y is in dictionary, x < y 
      return -1; 
     } 

     // otherwise return the comparison of the two 
     return x.CompareTo(y); 

     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 

     textBox1.Text = textBox1.Text.Replace("(", ""); 
     textBox1.Text = textBox1.Text.Replace(")", ""); 
     string[] items = textBox1.Text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 
     Array.Sort<string>(items, 0, items.Length, new Comparer()); 
     textBox2.Text = String.Join(Environment.NewLine, items); 

    } 

与输入

9988777 
CS01 
1234444 
CS11 
77888999 

它输出:

1234444 
77888999 
9988777 
CS01 
CS11 

一个主要缺陷在这里 - 这不会对项目排序正确,如果你是<列表中有一个项目4个字符 - 例如如果你输入99而不是9988777,它将无法正常工作。

为了解决这个问题,您需要清楚地确定您将拥有哪种类型的输入。