I have this variable called tasks:
var tasks = new List<string>();
Right now tasks has a count of 81, but this could change down the road.
What I am trying to do is 3 loops of tasks getting 28 at a time like so:
#for (var i = 0; i < 28; i++)
{
}
#for (var i = 28; i < 56; i++)
{
}
#for (var i = 56; i < 81; i++)
{
}
I do not like that I hard coded the numbers, so my question is using tasks.Count What would be the best way loop through an array getting 28 at a time?
Since you have clarified in the comments that what you really want to do is do something different after each block of 28 (or whatever) elements. For that you can make use of the % operator. For example:
//Keep this constant somewhere else or maybe in a config value so it is easily changed
private const int TasksPerPage = 28;
And now we can loop over your data while outputting a page break after 28 elements:
for(var i = 0; i < tasks.Count(); i++)
{
//You can remove the i>0 check if you want to output a break at the start
if (i % TasksPerPage == 0 && i > 0)
{
Console.WriteLine("Page Break");
}
Console.WriteLine(tasks[i]);
}
You can use Linq to take & skip a specific amount.
var tasks = new List<string>();
var groupSize = tasks.Count() / 3;
var groupOne = tasks.Take(groupSize);
var groupTwo = tasks.Skip(groupSize).Take(groupSize);
var groupThree = tasks.Skip(groupSize * 2).Take(groupSize);
foreach(var item in groupOne)
{
// Do Something
}
foreach(var item in groupTwo)
{
// Do Something
}
foreach(var item in groupThree)
{
// Do Something
}
Related
I want to use the bulk insert concept in C# once count reach 20.if we have 40 numbers no issue. but if we get 39 records got a problem, based on if the condition. how we able to avoid this problem. here below I added a simple program for reference.
var numbers = 39 // not static numbers
int count = 0;
for(int i=0; i<=numbers; i++)
{
count++;
if (count == 20)
{
//Logic
count = 0;
}
}
You can determine whether to batch insert the rest files by comparing the counter with the remaining number of files.
int num = 49;
int count = 0;
for(int i = 1; i <= num; i++)
{
count++;
var n = i / 20;
if(i % 20 == 0 ||count == (num - 20 * ( i / 20)))
{
//Logic
count = 0;
}
}
No need of count variable, you can use modulo operator inside for loop
Like
for(int i = 0; i <= numbers; i++)
{
//i != 0 to avoid bulk process at first
if(i != 0 && i % 20 == 0)
{
//Your bulk operation
}
}
I recommend you to use Console.WriteLine() to print value of i and counter in each iteration so that you will understand bug in your code.
var numbers = 39 // not static numbers
int count = 0;
for(int i=0; i<=numbers; i++)
{
count++;
//Print values to understand flow of program
Console.WriteLine($"For i = {i}, value of count is {count}");
if (count == 20)
{
Console.WriteLine("Time to reset count variable");
//Logic
count = 0;
}
}
You can use Linq .Skip() and .Take(), to do batches
var batchSize = 20;
var batchCount = files.Count() / batchSize;
for (int i = 0; i < batchCount; i++)
{
var bulkFiles = files.Skip(i * batchSize).Take(batchSize);
}
I am trying to create a draft order for a game I'm working on but I cannot get it to function how I need it to. I need 5 rounds with each round number properly and each pick should be numbered 1-10 for each round. Here is the code I'm working with:
List<Draft> _draftorder = new List<Draft>();
foreach (Team t in teams)
{
for (int i = 1; i <= 5; i++)
{
_draftorder.Add(new Draft()
{
city = t.city,
round = i++,
pick = i++,
});
}
}
Any help is appreciated!
I find the logic is easier to follow when the code matches the stepwise workflow of the requirements, and the variable names match the concepts in the requirements.
List<Draft> _draftorder = new List<Draft>();
for (int currentRound=1; currentRound<=10; currentRound++)
{
int pickOrder = 1;
foreach (Team t in teams)
{
_draftorder.Add(new Draft()
{
city = t.city,
round = currentRound,
pick = pickOrder++
});
}
}
You need to add an additional for loop and put the foreach loop inside the first for loop:
List<Draft> _draftorder = new List<Draft>();
// Allow 5 rounds
for (int i = 1; i <= 5; i++)
{
// Allow every team to pick some drafts
foreach (Team t in teams)
{
// Limit them to a specific amount of picks per round
for (int j = 1; j <= 10; j++)
{
_draftorder.Add(new Draft()
{
city = t.city,
round = i,
pick = j,
});
}
}
}
So I'm doing a practical that involves asking the user to input a score between 0 and 100. The program will keep track of the number of scores that have been entered, the total score (sum of all scores) and the average score.
To calculate the total score, I've come up of the idea of using a for loop that will cycle through my listbox and add each score to a variable (below).
int sTotal = 0;
for(int i = 0; i < lstScores.Items.Count; i++)
{
//Calculation occurs here
}
txtScoreTotal.Text = Convert.ToString(sTotal);
Thing is, I don't exactly know how to do it. I've tried searching to no avail. Any help would be greatly appreciated.
int sTotal = 0;
int Average = 0;
for(int i = 0; i < lstScores.Items.Count; i++)
{
bool result = Int16.TryParse(lstScores.Items[i],out int res);
if (result)
{
sTotale += res;
}
}
Average = sTotal / lstScores.Items.Count;
txtScoreTotal.Text = Convert.ToString(sTotal);
See this
int i = 0, result = 0;
while (i < lstScores.Items.Count)
{
result += Convert.ToInt32(lstScores.Items[i++]);
}
txtScoreTotal.Text = Convert.ToString(result);
I havent tried following, but you can try 1 line solution too
var sum = lstScores.Items.OfType<object>().Sum(x => Convert.ToInt32(x));
You need to handle exception if sum exceedes int.Max
Easiest is it to do with a foreach loop like this:
int sTotal = 0;
foreach (string item in lstScores.Items)
{
sTotal += Int32.Parse(item);
}
txtScoreTotal.Text = Convert.ToString(sTotal);
Excuse me for the silly question, but i can't manage to solve it.
How can i make something to happen every third time ?
Times(left number):
shipmentId=0
shipmentId=0
shipmentId=1
shipmentId=1
shipmentId=2
shipmentId=2 ....
int occurrence = 0;
int counter = 0;
foreach (var el in elmOrderData)
{
if (el.Name == "shipmentIndex")
{// we are entering here for every element that his name is "shipmentIndex"
el.SetValue(shipmentId);
secondTime++;
}
if ((secondTime % 2) == 0)
{// every third time we see "shipmentIndex"
secondTime = 1;
shipmentId++;
}
}
You could use a bool as in the following example. This will display messageboxes 1,3,5,7 and 9:
bool test = false;
for (int i = 0; i < 10; i++)
{
if (test)
MessageBox.Show(i.ToString());
test = !test;
}
Trying to piece together your notes - whether 'it' happens every time or not. How about this?
int occurrence = 0;
int counter = 0;
foreach(var a in list)
{
if(some_condition)
{
// do something..
occurrence++
if(occurrence % 2 == 0)
{
counter++
}
}
}
Why not just increment everytime and just divide by 2?
for(var i = 0; i<20; i++)
{
var j = i / 2; // or bit shift
//do work on j instead of i
}
Is there a way to use a loop that takes the first 100 items in a big list, does something with them, then the next 100 etc but when it is nearing the end it automatically shortens the "100" step to the items remaining.
Currently I have to use two if loops:
for (int i = 0; i < listLength; i = i + 100)
{
if (i + 100 < listLength)
{
//Does its thing with a bigList.GetRange(i, 100)
}
else
{
//Does the same thing with bigList.GetRange(i, listLength - i)
}
}
Is there a better way of doing this? If not I will at least make the "thing" a function so the code does not have to be copied twice.
You can make use of LINQ Skip and Take and your code will be cleaner.
for (int i = 0; i < listLength; i=i+100)
{
var items = bigList.Skip(i).Take(100);
// Do something with 100 or remaining items
}
Note: If the items are less than 100 Take would give you the remaining ones.
I didn't like any of the answers listed, so I made my own extension:
public static class IEnumerableExtensions
{
public static IEnumerable<IEnumerable<T>> MakeGroupsOf<T>(this IEnumerable<T> source, int count)
{
var grouping = new List<T>();
foreach (var item in source)
{
grouping.Add(item);
if(grouping.Count == count)
{
yield return grouping;
grouping = new List<T>();
}
}
if (grouping.Count != 0)
{
yield return grouping;
}
}
}
Then you can use it:
foreach(var group in allItems.MakeGroupsOf(100))
{
// Do something
}
You can keep an explicit variable for the end point:
for (int i = 0, j; i < listLength; i = j)
{
j = Math.min(listLength, i + 100);
// do your thing with bigList.GetRange(i, j)
}
In dotnet 6 you can use chunk:
//Child collections will be comprised of 10 elements each.
IEnumerable<int[]> sublists = numbers.Chunk(10);
https://exceptionnotfound.net/bite-size-dotnet-6-chunk-in-linq/
There is also a reference to use a group by to do this, which is quite an interesting solution for older versions of the framework:
Split a collection into `n` parts with LINQ?
List<int> list = null;
int amount_of_hundreds = Math.Floor(list.Count/100);
int remaining_number = list.Count - (amount_of_hundreds * 100);
for(int i = 0; i < amount_of_hundreds; ++i)
{
for(int j = 0; j < 100; ++j)
{
int item = list[(i * 100) + j];
// do what you want with item
}
}
for(int i = 0; i < remaining_number; ++i)
{
int item = list[(amount_of_hundreds * 100) + i];
// do what you want with item
}
you can try below approach also:
int i = 1;
foreach (item x in bigList)
{
batchOperation.Insert(x); //replace it with your action; create the batch
i++;
if (i >100)
{
table.ExecuteBatch(batchOperation); //execute the batch
batchOperation.Clear();
i = 1; // re-initialize
}
}
if (batchOperation.Count >= 1 )
{
table.ExecuteBatch(batchOperation); //do this for the residue items
}
This is my solution, before all, i skip the last rows (rows - skiplast) after i get top of the array.
[TestMethod]
public void SkipTake()
{
var rows = 100;
var skip = 1;
var skiplast = 95;
var result = Enumerable.Range(1, rows).Take(rows - skiplast).Skip(skip - 1 == 0 ? 1 : skip).ToList();
}
You can split one big List to many small lists by limit, like this:
var limit = 100;
foreach (var smallList in bigList.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / limit)
.Select(x => x.Select(v => v.Value).ToList())
.ToList())
{
Console.WriteLine($"{smallList.Count}");
Console.WriteLine(String.Join("\r\n", smallList));
}