Возьмите больше элементов из списка, чем на самом деле

1

Привет, я хочу взять 6 элементов из списка с 5 элементами. И я хочу начать брать предметы в заданной позиции. Мой результат должен быть сохранен в другом списке.

Например:

List_1 = 1, 2, 3, 4, 5  

Требуется 6 предметов

начать в позиции 2 {= 3}

List_result = 3, 4, 5, 1, 2, 3

List_1 = 7, 13, 6, 9, 17 

2 items needed  

начать в позиции 4 {= 17}

List_result = 17, 7

Я уже пробовал перебирать список с помощью for и foreach, но не смог найти реального решения. Любая помощь очень ценится!

  • 1
    Поделитесь кодом, который вы пробовали, и объясните, почему он не работает.
  • 0
    result = Enumerable.Range(start, count).Select(i => List[i % List.Count]); для общего подхода, см. мой ответ.
Теги:
list

5 ответов

0
using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        var data = new List<int>(5){1,2,3,4,5};
        var result = new List<int>(5);
        for(int i=0;i<5;i++)
        {
            result.Add(data[(i+2)%data.Count]);
        }
        for(int i=0;i<result.Count;i++)
        {
            Console.WriteLine(string.Format("{0}\n",result[i]));
        }
    }
}
0

Вы можете использовать это расширение:

public static IEnumerable<T> TakeSpinning<T>(this IEnumerable<T> source, int take, int position = 0)
{
    // skip check for invalid input like negative take or position
    int skip = position;
    int taken = 0;
    while (taken < take)
    {
        foreach (T element in source)
        {
            if (skip > 0)
            {
                skip--;
                continue;
            }
            yield return element;
            if (++taken == take) break;
        }
    }
}

Ваши образцы:

var List_1 = new List<int> { 1, 2, 3, 4, 5 };
var List_Result = List_1.TakeSpinning(6, 2).ToList();  // 3,4,5,1,2,3

var List_2 = new List<int> { 7, 13, 6, 9, 17 }; 
var List_Result2 = List_2.TakeSpinning(2, 4).ToList(); // 17,7
  • 0
    делает любопытные вещи , когда take и position являются отрицательными , но, если вы спросите глупый вопрос ...
  • 0
    @Jodrell: я оставляю эту задачу для OP, достаточно просто вызвать исключение, если take или pos недействительны.
Показать ещё 1 комментарий
0

просто,

public static IEnumerable<T> TakeLoop<T>(
        this IEnumerable<T> source,
        int count,
        int start = 0)
{
    if (start < 0)
    {
        throw new ArgumentOutOfRangeException("start");
    }

    if (count < 0)
    {
        throw new ArgumentOutOfRangeException("count");
    }

    using (var m = source.GetEnumerator())
    {
        for (var i = 0; i < count + start; i++)
        {
            if (!m.MoveNext())
            {
                if (i < start)
                {
                    throw new ArgumentOutOfRangeException("start");
                }

                m.Reset();
                m.MoveNext();
            }

            if (i >= start)
            {
                yield return m.Current;
            }
        }
    }
}

для использования, как это,

var result1 = (new[] { 1, 2, 3, 4, 5 }).TakeLoop(6, 3);

или это,

var result2 = (new[] { 7, 13, 6, 9, 17 }).TakeLoop(2, 4);
  • 0
    Что мне не нравится, так это то, что ему нужно создать новый список, который может быть дорогим, если он большой.
  • 0
    @TimSchmelter полностью согласен, я переписал свой ответ. Ловит также верхнее исключение для start . Нет ToList ing
0

Что-то подобное сделает трюк. Я написал это быстро, поэтому я уверен, что вы можете сделать это лучше

private IEnumerable<int> DoSomething(IEnumerable<int> set, int start, int num) {
    var taken = 0;
    var curSet = set.Skip(start);
    while (taken < num) {
        foreach(var current in curSet)
        {
            if (taken == num)
                yield break;
            yield return current;
            taken++;
        }
        curSet = set;
    }
}

Используйте следующее:

DoSomething(new int[] { 1,2,3,4,5}, 2, 6);
Урожайность:
3,4,5,1,2,3

  • 0
    делает любопытные вещи , когда take и position являются отрицательными , но, если вы спросите глупый вопрос ...
-1

его простая итерация, вы можете использовать простой цикл для этого:

List list;// add values
int itemNeeded; //set item need

int startPostion; //set the start postion
for(int i=0;i<itemNeeded;i++){
  add to newList the item at (startPosition++ % length of list)
}
  • 0
    не совсем действительный c #.
  • 0
    @Jodrell, который был ради объяснения решения, конечно, ответ должен быть изменен по мере необходимости

Ещё вопросы

Сообщество Overcoder
Наверх
Меню