Поиск по категориям и их хранение


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

Есть много для петель и много таблиц-проверка. Это занимает время, так как таблица довольно большая. Если это возможно, я хотел бы включить некоторые из петель, чтобы сократить время, затрачиваемое.

public partial class Stats : Form
{
    public Stats(ref TabControl languageTabs)
    {
        InitializeComponent();

        for (int i = 0; i < languageTabs.TabCount; i++)
        {
            Control[] ctrls = languageTabs.TabPages[i].Controls.Find(languageTabs.TabPages[i].Name + "Grid", true);
            DataGridView dgv = ctrls[0] as DataGridView;

            int charCount = 0;
            for (int j = 0; j < dgv.RowCount; j++)
            {
                charCount += (int)dgv.Rows[j].Cells[4].Value;
            }

            treeView1.Nodes.Add(languageTabs.TabPages[i].Text.ToUpper() + " Statistics");
            treeView1.Nodes[i].Nodes.Add("Total Number Of Strings: " + dgv.RowCount); // might need to remove '--' from count
            treeView1.Nodes[i].Nodes.Add("Total Number Of Chars: " + charCount);
            treeView1.Nodes[i].Nodes.Add("Total Number Of Strings and Chars per Category: ");

            //check for all different categories
            List<string> categories = new List<string>();

            int count = 0;
            for (int j = 0; j < dgv.RowCount; j++)
            {
                // look at every category in the dgv and see if we have a unique value in a container
                List<string> result = categories.FindAll(
                    delegate(string b)
                    {
                        return b == dgv.Rows[j].Cells[1].Value.ToString();
                    }
                );

                // if we don't have a unique ID then add it
                if (result.Count == 0)
                {
                    categories.Add(dgv.Rows[j].Cells[1].Value.ToString());
                }  
            }

            int[] categoryCount = new int[categories.Count];

            foreach (string cat in categories)
            {
                for (int j = 0; j < dgv.RowCount; j++)
                {
                    if (dgv.Rows[j].Cells[1].Value.ToString() == cat)
                    {
                        categoryCount[count]++;
                    }
                }
                count++;
            }

            int countTwo = 0;
            foreach (string cat in categories)
            {
                treeView1.Nodes[i].Nodes[2].Nodes.Add(cat + ":   " + categoryCount[countTwo].ToString());
                countTwo++;
            }

        }
    }


1028
4
c#
задан 7 декабря 2011 в 12:12 Источник Поделиться
Комментарии
4 ответа

Есть две пары петель, которые являются одинаковыми и могут быть объединены, как это:

int charCount = 0;
List<string> categories = new List<string>();
for (int j = 0; j < dgv.RowCount; j++)
{
charCount += (int)dgv.Rows[j].Cells[4].Value;

// look at every category in the dgv and see if we have a unique value in a container
List<string> result = categories.FindAll(
delegate(string b)
{
return b == dgv.Rows[j].Cells[1].Value.ToString();
}
);
// if we don't have a unique ID then add it
if (result.Count == 0)
{
categories.Add(dgv.Rows[j].Cells[1].Value.ToString());
}
}

treeView1.Nodes.Add(languageTabs.TabPages[i].Text.ToUpper() + " Statistics");
treeView1.Nodes[i].Nodes.Add("Total Number Of Strings: " + dgv.RowCount); // might need to remove '--' from count
treeView1.Nodes[i].Nodes.Add("Total Number Of Chars: " + charCount);
treeView1.Nodes[i].Nodes.Add("Total Number Of Strings and Chars per Category: ");

int[] categoryCount = new int[categories.Count];
int count = 0;
foreach (string cat in categories)
{
for (int j = 0; j < dgv.RowCount; j++)
{
if (dgv.Rows[j].Cells[1].Value.ToString() == cat)
{
categoryCount[count]++;
}
}

treeView1.Nodes[i].Nodes[2].Nodes.Add(cat + ": " + categoryCount[count].ToString());
count++;
}

Обратите внимание, что массив categoryCount больше не ncessary, и добавить ответ Саида и вы получите:

int charCount = 0;
List<string> categories = new List<string>();
for (int j = 0; j < dgv.RowCount; j++)
{
charCount += (int)dgv.Rows[j].Cells[4].Value;

if (!categories.Any(x=>x == dgv.Rows[j].Cells[1].Value.ToString()))
categories.Add(dgv.Rows[j].Cells[1].Value.ToString());
}

treeView1.Nodes.Add(languageTabs.TabPages[i].Text.ToUpper() + " Statistics");
treeView1.Nodes[i].Nodes.Add("Total Number Of Strings: " + dgv.RowCount); // might need to remove '--' from count
treeView1.Nodes[i].Nodes.Add("Total Number Of Chars: " + charCount);
treeView1.Nodes[i].Nodes.Add("Total Number Of Strings and Chars per Category: ");

foreach (string cat in categories)
{
int count = 0;
for (int j = 0; j < dgv.RowCount; j++)
{
if (dgv.Rows[j].Cells[1].Value.ToString() == cat)
{
count++;
}
}

treeView1.Nodes[i].Nodes[2].Nodes.Add(cat + ": " + count.ToString());
}

Затем, предполагая, что dgv.Строк реализует интерфейс IEnumerable вы можете сделать это для второго контура:

foreach (string cat in categories)
{
int count = dgv.Rows.Where(r => r.Cells[1].Value.ToString() == cat).Count();
treeView1.Nodes[i].Nodes[2].Nodes.Add(cat + ": " + count.ToString());
}

5
ответ дан 7 декабря 2011 в 12:12 Источник Поделиться

Кроме уже упомянутых очков, вы также можете улучшить код, сохраняя повторяющиеся объекта 'пути' во временных промежуточных переменных.

Е. Г. вы можете легко изменить следующий фрагмент кода ...

treeView1.Nodes.Add(languageTabs.TabPages[i].Text.ToUpper() + " Statistics");
treeView1.Nodes[i].Nodes.Add("Total Number Of Strings: " + dgv.RowCount); // might need to remove '--' from count
treeView1.Nodes[i].Nodes.Add("Total Number Of Chars: " + charCount);
treeView1.Nodes[i].Nodes.Add("Total Number Of Strings and Chars per Category: ");

... чтобы:

treeView1.Nodes.Add(languageTabs.TabPages[i].Text.ToUpper() + " Statistics");
var nodes = treeView1.Nodes[i].Nodes;
nodes.Add("Total Number Of Strings: " + dgv.RowCount); // might need to remove '--' from count
nodes.Add("Total Number Of Chars: " + charCount);
nodes.Add("Total Number Of Strings and Chars per Category: ");

4
ответ дан 7 декабря 2011 в 01:12 Источник Поделиться

Вы можете сократить некоторые части, такие как:

        for (int j = 0; j < dgv.RowCount; j++)
{
// look at every category in the dgv and see if
// we have a unique value in a container
List<string> result = categories.FindAll(
delegate(string b)
{
return b == dgv.Rows[j].Cells[1].Value.ToString();
}
);

// if we don't have a unique ID then add it
if (result.Count == 0)
{
categories.Add(dgv.Rows[j].Cells[1].Value.ToString());
}
}

К:

        for (int j = 0; j < dgv.RowCount; j++)
{
// look at every category in the dgv and see if
// we have a unique value in a container
// if we don't have a unique ID then add it

if (!categories.Any(x=>x == dgv.Rows[j].Cells[1].Value.ToString()))
categories.Add(dgv.Rows[j].Cells[1].Value.ToString());

}

После того, как вы измените его, так как это все часть ваш код будет более читабельным, и вы можете решить, как снять петли. На самом деле я предлагаю перейти от делегатов, лямбда-выражения, и использовать функции, связанные с LINQ в каждой части, а не только функций, которые решает ваши проблемы.

е.г в случае, если я писал любые возвраты первый раз нашли какой-либо продукт, а не перебирать все данные в категории.

3
ответ дан 7 декабря 2011 в 12:12 Источник Поделиться

Если у вас есть базовые источники данных вашей сети, вы могли бы упростить многое из того, что код с помощью группировка в LINQ.

Например, если у вас была система.Данных.Объект DataTable заполнение сетей, оператор LINQ, которые могут тянуть ваши категории и количество символов информация может быть следующим:

 var  categories = from row in table.AsEnumerable ()
group row by row [1] into groupedRows
select new { Value = groupedRows.Key,
Count = groupedRows.Count (),
CharSum = groupedRows.Sum (r => r.Field<int>(4))};
var charTotal = categories.Sum (c => c.CharSum);

0
ответ дан 7 декабря 2011 в 06:12 Источник Поделиться