Removing from a Collection - c#-3.0

I have a DataGridView collection object and check for a particular condition. If it is null, then I remove it from the DataGridView Collection. Here is my code -
foreach(DataGridViewRow dr in myDataGridViewRowCollection.Rows)
{
string title = TypeConvert.ToString(dr.Cells[Name].Value);
if(title == null)
//Remove it from the list.
myDataGridViewRowCollection.Rows.Remove(dr);
}
Now if I have 6 Rows in the myDataGridViewRowCollection and of them, 5 of them have title as null. Now, the above code removes only 3 of the 5 and not the remaining two.
I kind of understand the problem but I am not able to think right now of a solution. Any thoughts?

The problem is that you're changing the myDataGridViewRowCollection.Rows collection as you're iterating over it, which confuses/breaks the iterator. You need to seperate this into two steps. First make a list of what you need to remove, then you can actually remove them.
var toRemove = myDataGridViewRowCollection.Rows.Where(x => x.Cells[Name].Value == null);
foreach(var row in toRemove){
myDataGridViewRowCollection.Rows.Remove(row);
}

Related

Realm Swift - How to remove an item at a specific index position?

I am storing a simple list of id's as GUIDs in Realm, but would like the ability to delete an object at a particular index position.
So for example, I want to remove 04b8d81b9e614f1ebb6de41cb0e64432 at index position 1, how can this be achieved? Do I need to add a primary key, or is there a way to remove the item directly using the given index position?
Results<RecipeIds> <0x7fa844451800> (
[0] RecipeIds {
id = a1e28a5eef144922880945b5fcca6399;
},
[1] RecipeIds {
id = 04b8d81b9e614f1ebb6de41cb0e64432;
},
[2] RecipeIds {
id = cd0eead0dcc6403493c4f110667c34ad;
}
)
It seems like this should be a straightforward ask, but I can't find any documentation on it. Even a pointer in the right direction would do.
Results are auto-updating and you cannot directly modify them. You need to update/add/delete objects in your Realm to effect the state of your Results instance.
So you can simply grab the element you need from your Results instance, delete it from Realm and it will be removed from the Results as well.
Assuming the Results instance shown in your question is stored in a variable called recipes, you can do something like the following:
let recipeToDelete = recipes.filter("id == %#","04b8d81b9e614f1ebb6de41cb0e64432")
try! realm.write {
realm.delete(recipeToDelete)
}

Eloquent ORM: how do I remove a specific item from a collection inside the each function?

From the docs, I have this similar code:
$collection = $collection->each(function ($item, $key) {
if (/* some condition */) {
//I want to remove this specific item:
$item->delete(); //This is not working for me
//return false;
}
});
So given a certain condition, I want to delete that specific Item.
I use the ->delete() method but it doesn't work since I get the same count() results.
How do I remove those specific items?
I have tried ->pop() but it does delete the items from the database! I just want to remove those items only in the collection. :-P
Solution As suggested by Pawel Bieszczad, I tried with ->filter() function (There're so many nice methods that my mind got blocked) so I got it working like this:
$filtered = $projects->filter(function($item)use($app,$lastyear,$thisyear){
if(some_condition){
return $item; //I do want to keep this item in the collection.
}else{
//Don't do anything. Remove item. I don't want to keep this item in the collection.
}
});
You want to use the filter method

Possible to do two Group Bys and an if count check in one LINQ lambda statement?

Kind of a specific question but I wasn't sure how to approach it. I've got a list of rooms, that I am trying to group first by type, then by owner. I am doing this to check if there are duplicate rooms for a given owner and type (which shouldn't be possible so I need to prune them out). Right now my code looks like this:
IQueryable<IGrouping<Guid, Room>> allRoomsByOwner = _dbContext.Rooms.GroupBy(x => x.OwnerId);
List<Room> duplicates = new List<Room>();
foreach (IGrouping<Guid, Room> roomsByOwner in allRoomsByOwner)
{
IEnumerable<IGrouping<Guid, Room>> roomsOfOwnerByType = roomsByOwner.ToList().GroupBy(x => x.TypeId);
foreach (IGrouping<Guid, Room> grouping in roomsOfTypeByType)
{
if (grouping.Count() > 1)
{
duplicates.AddRange(grouping.ToList());
}
}
}
I'm just wondering if it's possible to put this all into one LINQ statement? I've got similar things before, but not quite this complex and not using two group bys. Thanks.
You can group by multiple columns ( OwnerId and TypeId) and flatten the groups with more than one elements (using the SelectMany method) to get the duplicates:
var duplicates = _dbContext.Rooms.GroupBy(x => new{x.OwnerId,x.TypeId})
.Where(g=>g.Count()>1)
.SelectMany(g=>g.Skip(1))// If you like you can skip the first element as representative of the group and the treat the rest as a duplicate.
.ToList();

Composite views in couchbase

I'm new to Couchbase and am struggling to get a composite index to do what I want it to. The use-case is this:
I have a set of "Enumerations" being stored as documents
Each has a "last_updated" field which -- as you may have guessed -- stores the last time that the field was updated
I want to be able to show only those enumerations which have been updated since some given date but still sort the list by the name of the enumeration
I've created a Couchbase View like this:
function (doc, meta) {
var time_array;
if (doc.doc_type === "enum") {
if (doc.last_updated) {
time_array = doc.last_updated.split(/[- :]/);
} else {
time_array = [0,0,0,0,0,0];
}
for(var i=0; i<time_array.length; i++) { time_array[i] = parseInt(time_array[i], 10); }
time_array.unshift(meta.id);
emit(time_array, null);
}
}
I have one record that doesn't have the last_updated field set and therefore has it's time fields are all set to zero. I thought as a first test I could filter out that result and I put in the following:
startkey = ["a",2012,0,0,0,0,0]
endkey = ["Z",2014,0,0,0,0,0]
While the list is sorted by the 'id' it isn't filtering anything! Can anyone tell me what I'm doing wrong? Is there a better composite view to achieve these results?
In couchbase when you query view by startkey - endkey you're unable to filter results by 2 or more properties. Couchbase has only one index, so it will filter your results only by first param. So your query will be identical to query with:
startkey = ["a"]
endkey = ["Z"]
Here is a link to complete answer by Filipe Manana why it can't be filtered by those dates.
Here is a quote from it:
For composite keys (arrays), elements are compared from left to right and comparison finishes as soon as a element is different from the corresponding element in the other key (same as what happens when comparing strings à la memcmp() or strcmp()).
So if you want to have a view that filters by date, date array should go first in composite key.

Linq to Entity - Explanation/Advice on behaviour Where() vs Where().ToList() in foreach loop

So the scenario in a nutshell: I have an entity (EF4) that has a foreign key to the primary key in the same entity (hierarchical structure) e.g.
MyEntityId (Primary Key)
ParentMyEntityId (Foreign key to Primary Key)
If I have a MyEntityList List<MyEntity> where the EntityState for both is Unchanged:
entity 1 - {MyEntityId = 10, ParentMyEntityId = null}
entity 2 - {MyEntityId = 11, ParentMyEntityId = 10}
and then I do this:
//Initially has 2 items in 'in' clause - iterates once and then exits because the EntityState of the second item has changed to Modified
foreach(MyEntity m in MyEntityList.Where(e => e.EntityState == System.Data.EntityState.Unchanged))
{
db.DeleteObject(m);
}
The first MyEntity is deleted, but the second changes to "Modified" and the foreach doesn't run a second time - I'm guessing due to the foreign key constraint.
However if I do:
//Iterates twice, even though the EntityState of the second item has changed to Modified
foreach(MyEntity m in MyEntityList.Where(e => e.EntityState == System.Data.EntityState.Unchanged).ToList())
{
db.DeleteObject(m);
}
Both entities are deleted (which is the desired effect).
Whilst I have a solution, I'm interested in why this happens, I was always under the impression that the iterator "set" that was defined at the start of the foreach loop remained the same, or threw a runtime error if you tried to modify it.
Should I not be using Where? Is there a better way to do this?
The iterator set is defined before the loop runs because you execute ToList (if you didn't do this it wouldn't be well defined).
So the iteration source is constant. But not the object you iterate over. The object references you get are constant but not the objects pointed to by them.
The version without ToList is equivalent to:
foreach(MyEntity m in MyEntityList) //always 2 items
{
//loop body always called two times
if (e.EntityState == System.Data.EntityState.Unchanged) //2 times
db.DeleteObject(m); //1 time
}
The ToList-version is equivalent to:
var copy = MyEntityList.Where(e => e.EntityState == System.Data.EntityState.Unchanged).ToList(); //always 2 items
foreach(MyEntity m in copy)
{
//loop body always called two times
db.DeleteObject(m); //2 times
}