I have an application that will continuously taking user's input and store the input in a List of class ItemsValue
How am I going to make it so that once the collection reaches 1000 counts, it will "stop" and a new collection will be created and so on.
For example:
List<ItemsValue> collection1 = new List<ItemsValue>();
//User input will be stored in `collection1`
if (collection1.count >= 1000)
//Create a new List<ItemsVales> collection2,
//and the user input will be stored in collection2 now.
//And then if collection2.count reaches 1000, it will create collection3.
//collection3.count reaches 1000, create collection4 and so on.
I don't know why, but you want a "list of lists": List<List<ItemsValue>>.
List<List<ItemsValue>> collections = new List<List<ItemsValue>>();
collections.Add(new List<ItemsValue>());
collections.Last().Add(/*user input*/);
if (collections.Last().Count >= 1000) collections.Add(new List<ItemsValue>());
I think you need List<List<ItemsValue>>
List<List<ItemsValue>> mainCollection = new List<List<ItemsValue>>();
int counter = 0;
if (counter == 0) mainCollection.Add(new List<ItemsValue>());
if(mainCollection[counter].Count < 1000) mainCollection[counter].Add(item);
else
{
mainCollection.Add(new List<ItemsValue>());
counter++;
mainCollection[counter].Add(item);
}
I don't know how is the rest of your code look like,but I would make that counter static.
Use a list of collections. If you have fixed size you can use a array instead of a list.
List<List<ItemsValue>> collections = new List<List<ItemsValue>>({new List<ItemsValue>()});
if(collections[collections.Count- 1].Count >= 1000)
{
var newCollection = new List<ItemsValue>();
// do what you want with newCollection
collections.Add(newCollection);
}
Try this:
List<List<ItemsValue>> collections = new List<List<ItemsValue>>({new List<ItemsValue>()});
if(collections[collections.Count-1].Count >= 1000)
{
collections.Add(new List<ItemsValue>());
}
Use the above if statement when you're adding an item to collections. To add an item to collections, use the following:
collections[collections.Count-1].Add(yourItem);
Related
I have a list that is populated with different values:
e.g
{GBP, GBP, GBP, USD}
so far I have this:
List<string> currencyTypes = new List<string>();
for (int i = 0; i < currencyTypes.Count; i++)
{
if currencyTypes[i] != [i]
console.writeline("currencies are different");
}
So if the list has all the same entries, the if statement shouldnt fire
e,g {GBP, GBP, GBP, GBP}
however if any of the values are different from the rest then the if statement should notice the difference and fire.
this doesnt work however.
any ideas?
You could use LINQ to test whether all entries are the same
if (currencyTypes.Distinct().Count() > 1) {
Console.WriteLine("currencies are different");
}
Slightly more efficient for long lists:
if (currencyTypes.Count > 1 && currencyTypes.Distinct().Skip(1).Any()) {
Console.WriteLine("currencies are different");
}
This is more efficient because Any iterates at most one element unlike Count which iterates the whole list.
First of all, your list is empty. Maybe it's for the sake of the example. If not, initialize it with data. However, modify line 3 and 5 to this to fix the problem.
for (int i = 1; i < currencyTypes.Count; i++)
{
if (currencyTypes[i] != currencyTypes[i-1])
....
}
you should first group your data and find your result depending the group.
eg
List<string> currencyTypes = new List<string>() {"USD", "GBP", "GBP", "GBP" };
// group list items
var typeGroup = currencyTypes.GroupBy(t => t);
if (typeGroup.Count() > 1)
Console.WriteLine("currencies are different");
// .
// .
// also you can check what item is unique
foreach (var t in typeGroup.Where(g => g.Count() == 1 ))
{
Console.WriteLine($"{t.Single()} is different");
}
I have a list whose size is not fixed. In each iteration, the number of elements in the list may get decreased, increased or remain same but with different values.
In each iteration, I receive the newer list in a setter as following:
public List<int> IconsColor
{
get { return iconsColorList; }
set
{
newIconsColorList = new List<int>(value);
if (newIconsColorList.Count == iconsColorList.Count && newIconsColorList.All(iconsColorList.Contains))
return;
//Else
nIconsChanged = true;
//??????????????????????????
//?????????- How do I update Old list with New values
//Something like iconsColorList = newIconsColorList;
//but above line makes the If-condition true since both the lists are same now
}
}
How do I modify the elements of the previous list (iconsColorList) with new values (present in newIconsColorList)? And if the number of elements in the new list is greater than to that of the older list then, add the new element to the older list also.
So you want to merge both lists (update and add new):
public List<int> IconsColor
{
set
{
for (int i = 0; i < Math.Min(iconsColorList.Count, value.Count); i++)
{
if (value[i] != iconsColorList[i])
{
iconsColorList[i] = value[i];
nIconsChanged = true;
}
}
if (value.Count > iconsColorList.Count)
{
// append new items to the end of the list
iconsColorList.AddRange(value.Skip(iconsColorList.Count));
nIconsChanged = true;
}
}
}
Side-note: i hope the lack of a getter was just because it wasn't relevant. A property without a getter is not really useful and smells like fish. In this case it would just return iconsColorList;.
Let's say I have two List<string>. These are populated from the results of reading a text file
List owner contains:
cross
jhill
bbroms
List assignee contains:
Chris Cross
Jack Hill
Bryan Broms
During the read from a SQL source (the SQL statement contains a join)... I would perform
if(sqlReader["projects.owner"] == "something in owner list" || sqlReader["assign.assignee"] == "something in assignee list")
{
// add this projects information to the primary results LIST
list_by_owner.Add(sqlReader["projects.owner"],sqlReader["projects.project_date_created"],sqlReader["projects.project_name"],sqlReader["projects.project_status"]);
// if the assignee is not null, add also to the secondary results LIST
// logic to determine if assign.assignee is null goes here
list_by_assignee.Add(sqlReader["assign.assignee"],sqlReader["projects.owner"],sqlReader["projects.project_date_created"],sqlReader["projects.project_name"],sqlReader["projects.project_status"]);
}
I do not want to end up using nested foreach.
The FOR loop would probably suffice. Someone had mentioned ZIP to me but wasn't sure if that would be a preferable route to go in my situation.
One loop to iterate through both lists (assuming both have same count):
for (int i = 0; i < alpha.Count; i++)
{
var itemAlpha = alpha[i] // <= your object of list alpha
var itemBeta = beta[i] // <= your object of list beta
//write your code here
}
From what you describe, you don't need to iterate at all.
This is what you need:
http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx
Usage:
if ((listAlpga.contains(resultA) || (listBeta.contains(resultA)) {
// do your operation
}
List Iteration will happen implicitly inside the contains method. And thats 2n comparisions, vs n*n for nested iteration.
You would be better off with sequential iteration in each list one after the other, if at all you need to go that route.
This list is maybe better represented as a List<KeyValuePair<string, string>> which would pair the two list values together in a single list.
There are several options for this. The least "painful" would be plain old for loop:
for (var index = 0; index < alpha.Count; index++)
{
var alphaItem = alpha[index];
var betaItem = beta[index];
// Do something.
}
Another interesting approach is using the indexed LINQ methods (but you need to remember they get evaluated lazily, you have to consume the resulting enumerable), for example:
alpha.Select((alphaItem, index) =>
{
var betaItem = beta[index];
// Do something
})
Or you can enumerate both collection if you use the enumerator directly:
using (var alphaEnumerator = alpha.GetEnumerator())
using (var betaEnumerator = beta.GetEnumerator())
{
while (alphaEnumerator.MoveNext() && betaEnumerator.MoveNext())
{
var alphaItem = alphaEnumerator.Current;
var betaItem = betaEnumerator.Current;
// Do something
}
}
Zip (if you need pairs) or Concat (if you need combined list) are possible options to iterate 2 lists at the same time.
I like doing something like this to enumerate over parallel lists:
int alphaCount = alpha.Count ;
int betaCount = beta.Count ;
int i = 0 ;
while ( i < alphaCount && i < betaCount )
{
var a = alpha[i] ;
bar b = beta[i] ;
// handle matched alpha/beta pairs
++i ;
}
while ( i < alphaCount )
{
var a = alpha[i] ;
// handle unmatched alphas
++i ;
}
while ( i < betaCount )
{
var b = beta[i] ;
// handle unmatched betas
++i ;
}
I have a List of different DayTime (Ticks). I try to get a list of the time remaining from now to each time element.
List<long> diffliste = new List<long>(m_DummyAtTime);
// 864000000000 ≙ 24h
diffliste.ForEach(item => { item -= now; if (item < 0) item += 864000000000; });
// test, does also not work
// diffliste.ForEach(item => { item -= 500; });
However, the list is not changed. Do I miss something?
(now is DateTime.Now.TimeOfDay.Ticks)
var times = diffliste.Select(ticks => new DateTime(ticks) - DateTime.Now);
Will return a collection of TimeSpans between now and each time.
Without using Linq:
List<TimeSpan> spans = diffliste.ConvertAll(ticks => new DateTime(ticks) - DateTime.Now);
(modified as suggested by Marc)
You are changing a standalone copy in a local variable (well, parameter actually), not the actual value in the list. To do that, perhaps:
for(int i = 0 ; i < diffliste.Count ; i++) {
long val = diffliste[i]; // copy the value out from the list
... change it
diffliste[i] = val; // update the value in the list
}
Ultimately, your current code is semantically similar to:
long firstVal = diffliste[0];
firstVal = 42;
which also does not change the first value in the list to 42 (it only changes the local variable).
You cannot change the value of an item inside a foreach cycle.
You can do it using a classic for cycle or creating and assigning items to a new list.
for (int i = 0 ; i < diffliste.Count; i++)
{
long value = diffliste[i];
// Do here what you need
diffliste[i] = value;
}
The iteration var in a foreach cycle is immutable, so you cannot change it. You either have to create a new list or use a for cycle... see also here.
i have this loop and it loops for large count like 30 000 times at least
i am looking for some way to improve it's performance
DbRecordDictionary is derived from DictionaryBase class
here is the loop:
ArrayList noEnter = new ArrayList();
DbRecordDictionary oldArray = new DbRecordDictionary();
DbRecordDictionary userArray = new DbRecordDictionary();
DbRecordDictionary result = null;
foreach (string key in keys)
{
if (noEnter.Contains(key))
{ //may need cast!
if (count < 1)
result.Add(key, userArray[key]);
else if (oldArray.Count == 0)
break;
else if (oldArray.Contains(key))
result.Add(key, userArray[key]);
}
}
You may want to use a Dictionary/Hashset for oldArray, but else there is not much you can do. Also noEnter if that is an array.
From what I can see, the variable count or the oldArray never changes during the loop, so you can place those condition outside the loop, and make two different loops.
if (count < 1) {
foreach (string key in keys) {
if (noEnter.Contains(key)) {
result.Add(key, userArray[key]);
}
}
} else if (oldArray.Count == 0) {
// no data
} else {
foreach (string key in keys) {
if (noEnter.Contains(key)) {
if (oldArray.Contains(key)) {
result.Add(key, userArray[key]);
}
}
}
}
The collections noEnter and oldArray should be dictionaries, otherwise you will be spending a lot of execution time in the Contains calls.
If noEnter has more then about 10 items in it, then use a Dictionary rathern then a List/Array for it. As a Dictionary can look up a item without having to look at all the items, when an List/Array has to loop over all items.
Otherwise consider shorting "keys" and "oldArray" and then proforming a "merge" on them. Look at the code for a "merge sort" to see how to do the merge. (This would need carefull profiling)
try this
(from k in keys
where noEnter.Contains(k) &&
oldArray.Count > 0 &&
count < 1 &&
oldArray.Contains(k)
select k)
.ToList()
.ForEach(k => result.Add(k, userArray[k]));
Small small optimization could be using generics
ArrayList noEnter = new ArrayList(); would be List noEnter = new List();
and DbRecordDictionary would inherit Dictonary instead of DictionaryBase.
im not 100% sure that you would gain performance but you will use a more modern c# style.