#c# #replace
#c# #заменить
Вопрос:
Если у меня есть список из 100 целых чисел, как я мог бы присвоить значения с индексом от 20 до 50 другому набору значений в списке длиной 31 без использования циклов? Исходя из python, это очень легко сделать без зацикливания, но я не уверен, возможно ли это сделать на c #.
Комментарии:
1. Когда вы говорите «без циклов», разрешено ли вам использовать что-то, что использует циклы, например LINQ?
2. Логически невозможно сделать это без циклов и без жесткого кодирования индексов. Пожалуйста, определите, чего вы на самом деле хотите
3. Как бы вы это сделали на Python? Мы могли бы показать вам что-то функционально эквивалентное.
Ответ №1:
Используя LINQ, который «без использования циклов в моем коде», вы могли бы:
hundredInts.Take(19).Concat(thirtyoneInts).Concat(hundredInts.Skip(50));
(и если вы хотите вернуть его в виде списка или массива и т.д., соответствующий вызов TOXX в конце его)
Или , возможно:
hundredInts.Select((n, i) => (i < 20 || i > 50) ? n : thirtyOneInts[i-20])
Или встроенный материал:
hundredInts.RemoveRange(20, 31).InsertRange(20, thirtyOneInts);
Комментарии:
1. Я бы действительно воздержался от того, чтобы говорить кому-то, кто не знает c #, что LINQ является решением для этого. Люди неправильно понимают и смотрят на меня как на сумасшедшего, когда я объясняю им, что linq не творит магию, а использует циклы
2. Хах., да .. Боюсь, будет много ввода, чтобы сделать это без циклов со списком!
3. Много CTRL C, CTRL V вы имеете в виду, ха-ха
4. Да, я думаю, я бы использовал sublime и textpastry
Ответ №2:
Нет никакого тривиального способа сделать это со списками. Однако это легко сделать с помощью массивов, используя Array.Copy:
var destIndex = 20;
Array.Copy(sourceArray, 0, destArray, destIndex, sourceArray.Length)
Ответ №3:
Что ж, если вы можете использовать петли под капюшоном, вы можете создать метод расширения, например
public static class MyExtensions{
public static void SetRange<T>(this List<T> source, IEnumerable<T> newValues, int startIndex){
var newValuesList = newValues.ToArray();
int numberOfElements = Math.Min(source.Count - startIndex, newValues.Count());
for(int i = 0; i < numberOfElements; i ){
source[i startIndex] = newValuesList[i];
}
}
}
И используйте, как показано ниже:
var list = Enumerable.Range(0, 100).ToList();
var list2 = Enumerable.Range(1000, 31).ToList();
list.SetRange(list2, 20);
Это заменит значения в list
, начиная с индекса 20, на значения list2
. Вы также можете изменить метод расширения, чтобы добавить другой параметр для определения количества элементов, из которых вы будете извлекать list2
, например, следующим образом:
public static void SetRange<T>(this List<T> source, IEnumerable<T> newValues, int startIndex, int numberOfElements){
var newValuesList = newValues.ToArray();
numberOfElements = Math.Min(numberOfElements, source.Count - startIndex);
numberOfElements = Math.Min(numberOfElements, newValues.Count());
for(int i = 0; i < numberOfElements; i ){
source[i startIndex] = newValuesList[i];
}
}
Вероятно, вам также следует добавить проверку, если startIndex
и numberOfElements больше или равно 0 .