ghost media
ghost media

Reputation: 25

How to make a foreach loop skip the item upon exception

How to make a foreach loop skip the item upon exception?

foreach (var item in items) 
{
   newItems.Add(new object
   {
      Name = item.name,
      Category= GetCategoryByName(item.name),
      AddedTime= DateTime.Now
   });
}

Let's say that in my List of items, I got 1000 objects, Each time I create a new object, I call for a function that looks up in a list and retrieves the categoryName by doing

private string GetCategoryByName (string name) 
{
   return CategoryList.Where( n=> n == name).First();
}

But it happens that the name doesn't exist in the Category list, which will cause an exception that no sequence match e.g.

What I wonder then is how can I just skip this item that doesn't exist in the category list? What I would like to do is to log the Name that doesn't exist in the CategoryList and continue to the next item. It feels like when the exception occurs on f.eks item with index 600, it just stops there and exits the foreach loop, with only 599/600 items. When it should continue and end up with 999 items (since one caused exception).

How can I fix this? I want to log and ignore all the items that causes exception due non-existent categoryname when looking up in the category list.

Upvotes: 0

Views: 450

Answers (3)

Enigmativity
Enigmativity

Reputation: 117029

Assuming that newItems is a List<object>() then you can do this:

newItems.AddRange(
    from item in items
    join category in CategoryList on item.name equals category
    select new
    {
        Name = item.name,
        Category = category,
        AddedTime = DateTime.Now
    });

Now, just in case CategoryList contains duplicates, then this is more in keeping with the original code:

newItems.AddRange(
    from item in items
    from category in CategoryList.Where(n => n == item.name).Take(1)
    select new
    {
        Name = item.name,
        Category = category,
        AddedTime = DateTime.Now
    });

To get the items that should be logged, do this: items.Where(item => !CategoryList.Any(n => n == item.name)).

Upvotes: 2

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

I suggest computing category before adding a new item:

    foreach (var item in items) {
        string category = CategoryList
          .FirstOrDefault(n => n == item.name);

        if (null == category) // we don't have category
            continue;

        newItems.Add(new object
          {
              Name      = item.name,
              Category  = category,
              AddedTime = DateTime.Now
          });
    }

Upvotes: 2

Nenad
Nenad

Reputation: 316

Something like this?

foreach (var item in items) 
{
    string catName = GetCategoryByName(item.name);

    if (catName != null)
    {
        newItems.Add(new object
        {
            Name = item.name,
            Category = catName,
            AddedTime = DateTime.Now
        });
    }
}

And fix

GetCategoryByName

to:

private string GetCategoryByName(string name) 
{
    return CategoryList.FirstOrDefault(n => n == name);
}

Upvotes: 1

Related Questions