Как заменить множественные значения в списке на c #?

#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 .