C #: Как упорядочить массивы в предопределенном пользовательском порядке только по первым 4 цифрам? - PullRequest
1 голос
/ 22 февраля 2010

Я хочу создать простой графический интерфейс C # с текстовым полем, чтобы пользователи могли вставлять содержимое и повторно копировать отсортированный контент.

Например, пользователь вставит это в поле:

part #        QTY
CS01-111-111  3
CS02-222-222  3
CS03-333-111  3
CS03-333-333  3 

Тогда я хочу, чтобы программа сортировала все, что вставлено в нее, вот так. Сортировка только по первым 4 цифрам, но после нее сохраняется значение QTY:

part #        QTY
CS03-333-111  3
CS03-333-333  3
CS01-111-111  3
CS02-222-222  3

У меня есть некоторый код C #, чтобы помочь мне сделать это, но он продолжает блокироваться.

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()
            {
                _order = new Dictionary<string, int>();
                _order.Add("CS01", 1);
                _order.Add("CS58", 2);
                _order.Add("CS11", 3);
            }

            public int Compare(string x, string y)
            {
                if (x.Length < 4 || y.Length < 4)
                    return x.CompareTo(y);
                if (!_order.ContainsKey(x.Substring(0, 4)) || !_order.ContainsKey(y.Substring(0, 4)))
                    return x.CompareTo(y);
                return _order[x.Substring(0, 4)].CompareTo(_order[y.Substring(0, 4)]);
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            string[] items = textBox1.Text.Split(Environment.NewLine.ToCharArray());
            Array.Sort<string>(items, 0, items.Length, new Comparer());
            textBox1.Text = String.Join(Environment.NewLine, items);
        }
    }
}

Есть идеи, что я могу сделать, чтобы это исправить?

Ответы [ 3 ]

6 голосов
/ 22 февраля 2010

Создайте компаратор, содержащий словарь для сортировки строк:

public class Comparer : IComparer<string> {

   private Dictionary<string, int> _order;

   public Comparer() {
      _order = new Dictionary<string, int>();
      _order.Add("03-33", 1);
      _order.Add("01-11", 2);
      _order.Add("02-22", 3);
   }

   public int Compare(string x, string y) {
      return _order[x.Substring(2, 5)].CompareTo(_order[y.Substring(2, 5)]);
   }

}

Тогда вы можете использовать компаратор в методе Array.Sort

string[] items = TheTextBox.Text.Split(new String[]{ Environment.NewLine});
Array.Sort<string>(items, 1, items.Length - 1, new Comparer());
TheTextBox.Text = String.Join(Environment.NewLine, items);
4 голосов
/ 23 февраля 2010

Вот пара модификаций кода, который я выложил ранее.

Изменения в конструкторе могут работать, а могут и не работать, но могут сэкономить при вводе.

Этот метод сравнения должен быть почти в два раза быстрее, потому что он делает вдвое меньше словарных поисков.

public class Comparer : IComparer<string>
{

    private Dictionary<string, int> _order;

    public Comparer()
    {
        List<string> list = new List<string>()
        {
            "CS01",
            "CS58",
            "CS11"
        };

        _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);
        }
    }
}
2 голосов
/ 23 февраля 2010

Он блокируется, потому что вы изменяете textBox1.Text внутри метода textBox1_TextChanged. Поэтому каждый раз, когда textBox1_TextChanged завершается, он вызывается снова с новым значением Text.

Вам нужно что-то вроде этого:

private bool _updating = false;
private void textBox1_TextChanged(object sender, EventArgs e)
{
    if (!_updating)
    {
        try
        {
            _updating = true;

            // do work ...

            textBox1.Text = ...
        }
        finally
        {
            _updating = false;
        }            
    }
}

или вы можете просто проверить значение перед изменением textBox1.Text:

string newValue = ... ;
if (textBox1.Text != newValue)
{
    textBox1.Text = newValue;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...