Yogesh Kumar Tyagi Ответов: 3

Проблема сортировки в алфавитно-цифровой коллекции строк в C#


Привет,
У меня есть коллекция, которая содержит числовую строку, буквенно-цифровую строку и null

как я сортирую эту коллекцию

Пример Данных

{"123","562","d586", "5", null, "689", " a896"}

Сортированный вывод: - {"a896", "d586","689","562","123","5"}

пожалуйста, помогите мне

Что я уже пробовал:

notNullableStateroomList = notNullableStateroomList.OrderByDescending(x => x.GetType()
                                                          .GetProperty((e.Column as GridViewDataColumn).GetDataMemberName().PadLeft(x.Stateroom.Length, '0')).GetValue(x, null))
                                                          .Concat(notNullableStateroomList.Where(x => isInteger(x.Stateroom)).OrderByDescending(x => Convert.ToInt32(x.Stateroom)));

F-ES Sitecore

Я не вижу никакого порядка в этом результате. Вам нужно будет четко объяснить, что диктует порядок.

Yogesh Kumar Tyagi

Мне нужно сначала отсортировать все буквенно-цифровые числа в порядке убывания, чем все числовые числа в порядке убывания, чем все нулевые числа в конце списка

3 Ответов

Рейтинг:
1

OriginalGriff

Это правильная сортировка: алфавитная сортировка работает путем сравнения каждого символа в каждой паре строк по одному, и результат всего сравнения основан на первом различном символе в двух строках. Таким образом, "1" - "9" идут перед "а" - "z" (которые идут после "а" - "Z"), поскольку именно в таком порядке символы появляются в наборе символов. После этого "100" приходит раньше "2", "20", "43", и так далее, потому что первое различие находится в первом символе.

Если вы хотите отсортировать их на основе любого числового значения, вам нужно использовать пользовательский компаратор, который разбивает строку на ее алфавитные и числовые компоненты, преобразует числовые данные в число (целое число, вероятно, прекрасно), а затем сравнивает точно так, как вы описываете.
Нетрудно написать, если хорошенько подумать о желаемых результатах.


Рейтинг:
0

FranzBe

Я бы в качестве первого шага вывел список источников из - под вашего контроля перед обработкой. Затем я извлекаю буквенно-цифровые части и сортирую их. В конце концов результаты объединяются. (Возможно, мне стоит взглянуть, что такое пользовательский компаратор)

void Main()
{
	
	string[] tokens = {"123","562","d586","5",null,"689","a896"};
	
	tokens.Dump(); // this is a linqpad command

    // https://stackoverflow.com/questions/7216883/linq-query-find-strings-based-upon-first-letter-b-w-two-ranges
	var start = "a";
	var end = "z";
	var regex = new Regex(string.Format("^[{0}-{1}]", start, end));
	var alphanumericalTokens = tokens
	                      .Where(x => !string.IsNullOrEmpty(x))
	                      .Where(x => regex.Match(x.ToLowerInvariant()).Success)
						  .ToList();

	var regex2 = new Regex("^[0-9]*$");
	var numericalTokens = tokens
		  		     .Where(x => !string.IsNullOrEmpty(x))
					 .Where(x => regex2.Match(x).Success)
					 .Select(int.Parse)
					 .OrderByDescending(x => x);
					 
	var numericalTokensAsStrings =  numericalTokens
               .Select(x => x.ToString()).ToList();				 

	var nullTokens = tokens
				 .Where(x => string.IsNullOrEmpty(x));

	alphanumericalTokens.Dump();
	numericalTokens.Dump();
	
	
	var mergedList = alphanumericalTokens.Union(numericalTokensAsStrings).ToList();
	mergedList.Dump();
}


Yogesh Kumar Tyagi

не могли бы вы рассказать мне о Dump (); методе

как я могу использовать его в visual studio

FranzBe

Если вы используете linqpad http://www.linqpad.net/ вы можете использовать метод .Dump () для легкой визуализации ваших данных. Вы можете скопировать и вставить фрагмент выше и посмотреть, что он работает (и изменить его). Если вы не используете linqpad, просто закомментируйте вызовы .Dump () и используйте вместо этого отладчик.

Рейтинг:
0

Maciej Los

Я хотел бы предложить, чтобы хелпер-класс белое, например:

public static class StringHelper
{
	public static int ToNumeric(string value)
	{
		int retval = Int32.MinValue;

		Int32.TryParse(value, out retval);
		if(value==null && retval==0) retval = Int32.MaxValue;		
		
		return retval;
	}

	public static string TypeName(string value)
	{
		string sName = string.Empty;
		int tmp = ToNumeric(value);
		if (tmp == Int32.MaxValue)
			sName = "A";
		else if(tmp==0)
			sName = "C";
		else
			sName = "B";
				
		return sName;
	}
}


Теперь вы можете написать запрос:
List<string> myValues = new List<string>(){"123","562","d586","5",null,"689","a896"};

var sortedList = myValues
    .OrderByDescending(x => StringHelper.TypeName(x))
    .ThenByDescending(x => StringHelper.ToNumeric(x))
    .ToList();

Результат:
d586 
a896 
689 
562 
123 
5 
null 


Примечание: Вы должны улучшить это, потому что я немного занят сегодня и не буду выделять на это больше времени.