Как удалить каждый элемент N в списке, пока значение List.Count не превысит целевого значения? - PullRequest
0 голосов
/ 07 февраля 2019

Есть список коротких.Его значения не имеют значения, например:

List<short> resultTemp = new List<short>{1,2,3,4,5,6,7,8,9...};

Этот код должен уменьшить количество списка результатов, удалив из него каждый N-й элемент.

Пример 1:

List<short>{1,2,3,4,5,6,7,8,9,10}.Count == 10;
var targetItemsCount = 5;

результат должен быть {1,3,5,7,9}, а result.Count должен быть == 5

Пример 2:

List<short>{1,2,3,4,5,6,7,8,9}.Count == 9;
var targetItemsCo:nt = 3;

результат должен быть {1,4,7} и result.Count должно быть == 3

Но он должен прекратить его удаление, где-то для счетчика make result равным targetItemsCount (42 в этом коде, но его значение в другом случае не имеет значения).Код:

var currentItemsCount = resultTemp.Count;

var result = new List<short>();

var targetItemsCount = 42;
var counter = 0;
var counterResettable = 0;

if (targetItemsCount < currentItemsCount)
{
    var reduceIndex = (double)currentItemsCount / targetItemsCount;

    foreach (var item in resultTemp)
    {
        if (counterResettable < reduceIndex || 
            result.Count + 1 == currentItemsCount - counter)
        {
            result.Add(item);
            counterResettable++;
        }
        else
        {
            counterResettable = 0;
        }
        counter++;
    }
}

И resault.Count в этом примере равно 41, но должно быть == targetItemsCount == 42;

Как мне удалить каждый элемент N в списке доList.Count больше, чем целевое значение с C #?

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Дайте этому попытку:

var resultTemp = Enumerable.Range(1, 9).ToList();
var targetItemsCount = 3;

var roundingError = resultTemp.Count % targetItemsCount;
var reduceIndex   = (resultTemp.Count - roundingError) / targetItemsCount;

List<int> result;
if (reduceIndex <= 1)
    result = resultTemp.Take(targetItemsCount).ToList();
else
    result = resultTemp.Where((a, index) => index % reduceIndex == 0).Take(targetItemsCount).ToList();

Пробовал это на вашем примере, также дал 42 вращение со списком от 1 до 100, он удалит каждый элемент 2ndпока он не достигнет 42, поэтому последняя запись в списке будет 83.

Как я уже сказал, попробуйте и дайте мне знать, соответствует ли это вашему требованию.

0 голосов
/ 07 февраля 2019

Чтобы гарантировать получение ожидаемого количества выбранных элементов:

double increment = Convert.ToDouble(resultTemp.Count) / targetItemsCount;

List<short> result = Enumerable.Range(0, targetItemsCount).
                                Select(x => resultTemp[(int)(x * increment)]).
                                ToList();

Обратите внимание, что в следующем случае

List<short>{1,2,3,4,5,6,7,8,9}.Count == 9;
var targetItemsCount = 6;

Результатом будет [1, 2, 4, 5, 7, 8], то есть округление индексавниз при необходимости

Кроме того, вам необходимо добавить проверку (targetItemsCount > 0, targetItemsCount < resultTemp.Count ...)

Ссылка на Fiddle

0 голосов
/ 07 февраля 2019

Если мое понимание верно:

public static void run()
{
    var inputs =
        new List<Input>{
          new Input{ 
              Value = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },`
              TargetCount = 5, ExpectedOutput= new List<int>{1,3,5,7,9} 
          },
          new Input{  
              Value = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
              TargetCount = 3, ExpectedOutput= new List<int>{1,4,7} 
          },
        };

    foreach (var testInput in inputs)
    {
        Console.WriteLine($"# Input = [{string.Join(", ", testInput.Value)}]");
        var result = Reduce(testInput.Value, testInput.TargetCount);
        Console.WriteLine($"# Computed Result = [{string.Join(", ", result)} ]\n");
    }
}

static List<int> Reduce(List<int> input, int targetItemsCount)
{
    while (input.Count() > targetItemsCount)
    {
        var nIndex = input.Count() / targetItemsCount;
        input = input.Where((x, i) => i % nIndex == 0).ToList();
    }
    return input;
}

class Input
{
    public List<int> ExpectedOutput;
    public List<int> Value;
    public int TargetCount;
}

Результат:

Ввод = [1, 2, 3, 4, 5, 6, 7, 8, 9,10]
Вычисленный результат = [1, 3, 5, 7, 9]

Ввод = [1, 2, 3, 4, 5, 6, 7, 8, 9]
ВычисленоРезультат = [1, 4, 7]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...