Относительно сортировки многомерных массивов в C # - PullRequest
0 голосов
/ 15 сентября 2011

Я пытаюсь найти способ правильно отсортировать кучу разных массивов. Я публикую статьи контента, и каждое значение [0] в массиве будет относиться ко всем другим значениям [0]. и так далее. Каждый элемент составляет собирательные части полного элемента контента.

Теперь последний элемент популярности - это количество кликов, которое получил элемент. Как я делать элементы контента в зависимости от популярности, не смешивая HTML для каждой статьи?

* РЕДАКТИРОВАТЬ Я ограничен .NET 2.0 Framework на работе *

Ниже приведен код ... спасибо.

public class MultiDimDictList : Dictionary<string, ArrayList> { } 

myDicList.Add("fly", a_fly);
myDicList.Add("img", a_img);
myDicList.Add("bar", a_bar);
myDicList.Add("meter", a_meter);
myDicList.Add("block", a_block);
myDicList.Add("popularity", a_pop);

Ответы [ 3 ]

1 голос
/ 15 сентября 2011

Если вы используете следующий код, вы можете преобразовать свой существующий словарь массивов в коллекцию словарей, что позволит выполнять простую сортировку с использованием Linq OrderBy

// Get the shortest arraylist length (they should be equal this is just a paranoia check!)
var count=myDicList.Values.Min(x=>x.Count); 
// Get the collection of Keys
var keys=myDicList.Keys;
// Perform the conversion
var result=Enumerable.Range(0,count).Select(i=>keys.Select(k=>new {Key=k,Value=myDicList[k][i]}).ToDictionary(x=>x.Key,x=>x.Value)); 

var sorted=result.OrderByDescending(x=>x["popularity"]).ToList()

- РЕДАКТИРОВАТЬ ВЕРСИЮ ДЛЯ .NET 2.0

Сначала вам нужен класс сравнения

class PopularityComparison : IComparer<Dictionary<string,object>> {
    private bool _sortAscending;

    public PopularityComparison(bool sortAscending) {
        _sortAscending = sortAscending;
    }

    public int Compare(Dictionary<string, object> x, Dictionary<string, object> y) {
        object xValue = x["popularity"];
        object yValue = y["popularity"];

        // Sort Ascending
        if (_sortAscending) {
            return Comparer.Default.Compare(xValue, yValue);
        } else {
            return Comparer.Default.Compare(yValue, xValue);
        }

    }
}

Тогда вы можете использовать следующий код

// Get the shortest arraylist length (they should be equal this is just a paranoia check!) 
// Replacement for min 
int count = int.MaxValue;
foreach (ArrayList a in myDicList.Values) if (a.Count < count) count = a.Count;
// Get the collection of Keys 
Dictionary<string, ArrayList>.KeyCollection keys = myDicList.Keys;
// Perform the conversion 
List<Dictionary<string, object>> result = new List<Dictionary<string, object>>(count);
for (int i = 0; i < count; i++) {
  Dictionary<string, object> row = new Dictionary<string, object>(keys.Count);
  foreach (string key in keys) row.Add(key, myDicList[key][i]);
  result.Add(row);
}

А потом, наконец, отсортировать по возрастанию популярности порядка

result.Sort(new PopularityComparison(true));

или по убыванию

result.Sort(new PopularityComparison(true));
0 голосов
/ 15 сентября 2011

Это было бы намного проще, если бы у вас был список объектов статьи, каждый из которых содержал свойства для fly, img, bar, popularity и т. Д. Но если вам действительно нужно хранить вещи, используяэтот подход наизнанку, тогда единственный способ сортировки элементов контента по популярности - создать другой массив (или список) для хранения порядка.

Создайте новый список и заполните его последовательными индексами:

List<int> OrderedByPopularity = new List<int>();
ArrayList popList = myDicList["popularity"];
for (int i = 0; i < popList.Count; ++i)
{
    OrderedByPopularity.Add(i);
}

Теперь у вас есть список, который содержит индексы элементов в списке популярности.Теперь вы можете сортировать:

OrderedByPopularity.Sort((i1, i2) => return popList[i1].CompareTo(popList[i2]););

Но это дает вам наименее популярную статью в первую очередь.Если вы хотите изменить сортировку таким образом, чтобы OrderedByPopularity[0] был самым популярным элементом:

OrderedByPopularity.Sort((i1, i2) => { return popList[i2].CompareTo(popList[i1]);});

Действительно, вы должны обратить внимание на реструктуризацию своего приложения.Гораздо проще работать с объектами, имеющими свойства, чем пытаться поддерживать параллельные массивы свойств.

Если вам нужно сделать это в .NET 2.0, объявите массив poplist в области видимости класса (а не методобласть) и создайте метод сравнения.

ArrayList poplist;
void MyMethod()
{
    List<int> OrderedByPopularity = new List<int>();
    popList = myDicList["popularity"];
    for (int i = 0; i < popList.Count; ++i)
    {
        OrderedByPopularity.Add(i);
    }
    OrderedByPopularity.Sort(PopularityComparison);
    // ...
}

int PopularityComparison(int i1, int i2)
{
    return ((int)popList[i2]).CompareTo((int)popList[i1]);
}
0 голосов
/ 15 сентября 2011

Я думаю, что было бы лучше иметь объект, содержащий ваши ключи в качестве свойств, а не одну коллекцию с каждым элементом, который у вас будет в списках массивов.

Таким образом, вы получитесортировка по одной коллекции, которая становится тривиальной при использовании Linq.OrderBy ().

что-то вроде ...

public class Article
{
   public string Fly{get;set;}
   public string Img{get;set;}
   // etc.
   public float Popularity{get;set;}
}

Тогда ...

List<Article> articles = ... get from somewhere, or convert from your array lists.
List<Article> sorted = articles.OrderBy(a=>a.Popularity).ToList();

Пожалуйста, извинитекод салфетки здесь ... Я обновлю его, если вам нужно больше подробностей.

Пример использования non-linq.

Создание реализации IComparer.

public class ArticleComparer : IComparer<Article>
{
    public bool Accending { get; set; }

    public int Compare(Article x, Article y)
    {
        float result = x.Popularity - y.Popularity;

        if (!Accending) { result *= -1; }

        if (result == 0) { return 0; }
        if (result > 0) return 1;
        return -1;
    }
}

Затем, когда вы собираетесь отсортировать список, вы можете сделать что-то вроде следующего:

ArticleComparer comparer = new ArticleComparer();
comparer.Accending = false;
articles.Sort(comparer);
...