I`m trying to make a query in robomongo but there seems to be too many results in the query.
List<DataObject> list = collection.FindAs<DataObject>(Query.EQ("Item1", "Value1")).ToList();
foreach (DataObject item in list)
{
//Do Something
}
From what i read, i would need to use MongoCursor, but I couldnt find a good example, is there iterate through everything using batches of 1000?
Something like:
MongoCursor<DataObject> cursor = collection.FindAs<DataObject>(Query.EQ("Item1", "Value1"));
int batchNumber = 1000;
List<DataObject> list;
while(list = cursor.getBatch(batchNumber);)
{
foreach (DataObject item in list)
{
//Do Something
}
}
Now I understood i could easily solve this if i dont save it in a list before the foreach by doing :
foreach (DataObject item in collection.FindAs<DataObject>(Query.EQ("Item1", "Value1")))
{
//Do Something
}
This was solved by not saving the result in a list before the foreach. Like this
foreach (DataObject item in collection.FindAs<DataObject>(Query.EQ("Item1", "Value1")))
{
//Do Something
}
Related
I have the following code where I am checking if some elements are not matching in my dictionary then I want to remove the unmatching elements from the local item. The problem is, When a value is removed from the collection, for some reason it also modifies the parental structure.
My other problem is, for example if I have list as "A","B","B", using the Except is only giving me the single B but not the other. Please help.
public void AddLogs(IEnumerable<ReportGenerationTypes> subElements)
{
var changeDetails = new Dictionary<AuditSaveHeader, List<string>>();
List<string> AuditableItems = null;
List<string> subItems = new List<string>();
foreach (var item in subElements)
{
subItems.Add(item.ToString());
}
foreach (var item in auditLogData?.AuditHeaders)
{
if (!changeDetails.ContainsKey(item))
{
changeDetails.Add(item, null);
}
AuditableItems = new List<string>();
foreach (var inner in item.AuditChangeValues)
{
AuditableItems.Add(inner.Auditable.ToString());
}
changeDetails[item] = AuditableItems;
}
for (int i = 0; i < changeDetails.Count; i++)
{
var result = kp.Value.Except(subItems);
Auditable AuditItem = Auditable.Unassigned;
//I think the problem lies with the below code not sure.
if (result != null && result.Count() > 0)
{
foreach (var item in result)
{
Enum.TryParse(item, out AuditItem);
var itemToRemove = kp.Key.AuditChangeValues.Where(x => x.Auditable == AuditItem).FirstOrDefault();
//The following line effects the AuditChangeValues object and not just my dictionary.
kp.Key.AuditChangeValues.Remove(itemToRemove);
}
}
}
}
Promoting my comment to answer:
You are using some vars that are not shown, like kp, auditLogData, etc. and overall is not clear what you want to achieve.
Anyway I agree the problem is you are editing the reference to an object. You could try cloning the objects, etc. But without really understanding the code is hard to tell.
As part of this question, it was pointed out repeatedly that I had an O(n^2) problem using code similar to this...
public class Foo
{
public string IdentityValue {get;set;}
public string Prop1 {get;set;}
public string Prop2 {get;set;}
}
List<Foo> itemSet1 = GenerateLargeItemSet(); //makes a large list, > 5000 items for example
List<Foo> itemSet2 = GenerateLargeItemSet();
foreach (var itemFromSet1 in itemSet1)
{
//does a corresponding item exist in itemSet2?
var itemSet2Item = itemSet2.FirstOrDefault(i => i.IdentityValue == itemFromSet1.IdentityValue);
if (itemSet2Item != null)
{
//do stuff to create item in the persistent store
}
else
{
//do stuff to update item in the persistent store
}
}
Excusing the string comparison and parallelization considerations, is there a cheap and generic (objects may be type T, and the Identity property may be something else) way to reduce the O(n^2) nature of this?
One of solutions is to use Enumerable.Join method which have complextiy O(n)
List<Foo> itemSet1 = GenerateLargeItemSet(); //makes a large list, > 5000 items for example
List<Foo> itemSet2 = GenerateLargeItemSet();
// O(n)
var joinedSet = itemSet1.Join(itemSet2, s1 => s1.IdentityValue, s2 => s2.IdentityValue, (f1, f2) => f1).ToList();
// O(n)
foreach (var joinedItem in joinedSet)
{
//do stuff to create item in the persistent store
}
// O(n)
var unjoinedSet = itemSet1.Except(joinedSet);
// O(n)
foreach (var unjoinedItem in unjoinedSet)
{
//do stuff to update item in the persistent store
}
A well known way of improving the database queries speed is creating an index. The same principle can be applied here. But what is an index? It's just a data structure that allows fast searching. In BCL such structure is called Dictionary. So you can use something like this which will have O(N) time complexity
If the value is unique inside the set
var item2Index = itemSet2.ToDictionary(item => item.IdentityValue);
If not
var item2Index = itemSet2.GroupBy(e => e.IdentityValue)
.ToDictionary(g => g.Key, g => g.First());
and then
foreach (var itemFromSet1 in itemSet1)
{
//does a corresponding item exist in itemSet2?
Foo itemSet2Item;
if (!item2Index.TryGetValue(itemFromSet1.IdentityValue, out itemSet2Item))
{
//do stuff to create item in the persistent store
}
else
{
//do stuff to update item in the persistent store
}
}
If you want just to check for a duplicate item in the second set, but don't actually need the duplicate item, then you can use a simple HashSet (another BCL data structure for fast lookup)
var item2Keys = new HashSet<string>(itemSet2.Select(e => e.IdentityValue));
foreach (var itemFromSet1 in itemSet1)
{
//does a corresponding item exist in itemSet2?
if (!item2Keys.Contains(itemFromSet1.IdentityValue))
{
//do stuff to create item in the persistent store
}
else
{
//do stuff to update item in the persistent store
}
}
You can create Dictionary<TKey, TValue> first and then use its fast lookups it provides almost O(1) :
List<Foo> itemSet1 = GenerateLargeItemSet(); //makes a large list, > 5000 items for example
Dictionary<string, Foo> itemSet2 = GenerateLargeItemSet().ToDictionary(i => i.IdentityValue);
//O(N)
foreach (var itemFromSet1 in itemSet1)
{
//O(1)
if (!itemSet2.ContainsKey(itemFromSet1.IdentityValue))
{
//do stuff to create item in the persistent store
}
else
{
//do stuff to update item in the persistent store
}
}
You may find a performance improvement with the use of a HashSet.
List<Foo> itemSet1 = GenerateLargeItemSet(); //makes a large list, > 5000 items for example
HashSet<Foo> itemSet2 = new HashSet<Foo>(GenerateLargeItemSet());
foreach (var itemFromSet1 in itemSet1)
{
//does a corresponding item exist in itemSet2?
if (itemSet2.Contains(itemFromSet1))
{
//do stuff to update item in the persistent store
}
//do stuff to create item in the persistent store
}
I am working on an windows application and I am wondering what is the way to loop through an array of checkBox to see if they are checked or not and have a message box to show what is checked.
Here is the code i am using.
CheckBox[] myCheckBoxArray = new CheckBox[6];
myCheckBoxArray[0] = checkBoxALL;
myCheckBoxArray[1] = checkBoxA;
myCheckBoxArray[2] = checkBoxB;
myCheckBoxArray[3] = checkBoxC;
myCheckBoxArray[4] = checkBoxD;
myCheckBoxArray[5] = checkBoxE;
foreach(var items in myCheckBoxArray)
{
if(myCheckBoxArray.Checked)
{
MessageBox.Show(items);
}
}
You can use linq:
foreach(var checkedItem in myCheckBoxArray.Where(item => item.Checked))
{
MessageBox.Show(checkedItem);
}
You are looping through myCheckBoxArray, where items represent each item in the array, so you have to check whether the item is checked or not not the myCheckBoxArray.Checked. so your code will be like the following:
foreach(var items in myCheckBoxArray)
{
if(items.Checked)
{
//Do your stuff here
}
}
Dont loop not checked items .
var checkeeditems=myCheckBoxArray.where(p=>p.Cheked).toList();
foreach(var Name in checkeeditems)
{
MessageBox.Show(Name );
}
In the example code, you are looping through mycheckboxarray, but you are checking Checked property of myCheckBoxArray rather than item. You can alter the code as below and it will give you desired results.
foreach (var checkbox in myCheckBoxArray)
{
if (checkbox.Checked)
{
MessageBox.Show("this one is checked");
}
}
I am having some problems writing a recursive algorithm.
I have an item that affects other items.
Each of the affected items might affect other items...etc.
With a limited number of steps I might write:
var tempAffected = new List<Item>();
foreach(var item2 in item1.affectedItems)
{
if(item2.affectedItems > 0)
{
foreach(var item3 in item2.affectedItems)
{
if(item3.affectedItems > 0)
{
...
tempAffected.AddRange(item3.affectedItems)
tempAffected.Add(item3);
}
else
tempAffected.AddItem(item3);
}
}
else
tempAffected.AddItem(item2);
}
But I would like something recursive.
Any help would be appreciated.
EDIT
The final code ended up looking like this, after a few modifications in my code.
var tempAffected = new List<HSGameItem>();
var stack = new Stack<HSGameItem>(affected);
Func<HSGameItem, List<HSGameItem>> affectedForItem = item => {
if (item.booster.accounted)
return new List<HSGameItem> ();
item.booster.accounted = true;
return item.booster.affected;
};
while(stack.Count > 0)
{
var childrenParent = stack.Pop();
foreach (var child in affectedForItem(childrenParent))
{
tempAffected.AddUnique(child);
stack.Push(child);
}
}
tempAffected.ForEach(x => x.state.Matched(mType, length));
I had to mark every item that i already affected as "accounted" to make sure i wouldn't check it again.
So basically you want to collect all affected items into a temporary list called TempAffected, right?
Then you could do:
public List<Item> tempAffected = new List<Item>();
AddAffectedToDerived(item1, tempAffected);
private AddAffectedToDerived(Item root, List<Item> derived)
{
if (root.AffectedItems != null)
{
foreach(Item itemX in root.AffectedItems)
{
AddAffectedToDerived(itemX);
}
}
derived.Add(root);
}
That should do the trick for you.
Mind you, if your data structures are very large, you may want to use an iterative approach rather than a recursive instead because of the risk of stack overflow.
IMHO, the simplest implementation might look something like this:
IEnumerable<Item> GetAffectedItems(Item item)
{
foreach (Item affectedItem in item.affectedItems)
{
foreach (Item subItem in GetAffectedItems(affectedItem))
{
yield return subItem;
}
}
yield return item;
}
That said, note that the above will instantiate a large number of iterators (but at least that's better than creating a lot of copies of the data itself!). It's simple to write, but may not be as efficient as some other mechanism for enumerating all of the affected items.
As an example, an alternative would be to just build a List<Item> as you recurse (more similar to your original example):
List<Item> GetAffectedItems(Item item)
{
List<Item> list = new List<Item>();
GetAffectedItems(item, list);
return list;
}
void GetAffectedItems(Item item, List<Item> list)
{
foreach (Item affectedItem in item.affectedItems)
{
GetAffectedItems(affectedItem, list);
}
list.Add(item);
}
This is embedded in another loop, and well, it's pretty slow. Is there a better way to do this?
for(int i=0;i< listView.Items.Count;i++)
{
if(listView.Items[i].SubItems[3].Text == "asdf")
{
}
}
Well there's a nicer way to do it:
foreach (ListViewItem item in listView.Items)
{
if (item.SubItems[3].Text == "asdf")
{
...
}
}
Or you could use LINQ:
var query = listView.Items
.Cast<ListViewItem>()
.Where(item => item.SubItems[3].Text == "asdf");
foreach (var item in query)
{
...
}
I doubt that that will be faster though...
Does your outer loop change the listView? If not, could you do the query once and reuse the results in the outer loop?
In case someone runs across this using WPF, you don't get .SubItems on item when you use foreach (ListViewItem item in listView.Items). Instead, I found I could just use DataRowView and get the value of the cell that way:
foreach (DataRowView drv in listView.Items)
{
if (drv.Row[3].ToString() == "asdf")
{
...
}
}
You do have to add a using System.Data; statement at the top of your class to use it. I found it worked in WPF, and it might in other areas (i.e. WinForms), as well.