The LINQ “Select” statement to get rid of extraneous looping

In the previous post, I included this code to show how to build a list of element id’s that could then be used with Document.Delete

It finds all ImportInstance elements that are not linked, and then iterates through those elements in the foreach loop to create a list of their IDs.

    IList<ElementId> toDelete = new List<ElementId>();
    foreach (ImportInstance ii in new FilteredElementCollector(doc)
         .OfClass(typeof(ImportInstance))
         .Cast<ImportInstance>()
         .Where(i => i.IsLinked == false))
        {
            toDelete.Add(ii.Id);
        }   

But that foreach loop looks ugly (to me) and so I wanted to share a simplification that allows you to get rid of that loop and build this list of IDs directly.

The LINQ Select statement takes a lambda expression (in this case an expression taking a type ImportInstance represented as i). It returns whatever you want it to, in this case the ElementId returned from the i.Id property.

    IList<ElementId> toDelete =  new FilteredElementCollector(doc)
        .OfClass(typeof(ImportInstance))
        .Cast<ImportInstance>()
        .Where(i => i.IsLinked == false)
        .Select(i => i.Id)
        .ToList();
Advertisements

6 thoughts on “The LINQ “Select” statement to get rid of extraneous looping

  1. Hi again.

    I’m getting the following error when trying to build the macro “Error CS0103: The name ‘doc’ does not exist in the current context Build failed. (00:00:00.4020402)”
    I’m in the starting-phase of understanding this part of REVIT and therefore, I do not understand the error.

  2. My macro now looks like this:
    public void deleteImportsNotLinks()
    {
    Document doc = this.ActiveUIDocument.Document;

    IList toDelete = new FilteredElementCollector(doc)
    .OfClass(typeof(ImportInstance))
    .Cast()
    .Where(i => i.IsLinked == false)
    .Select(i => i.Id)
    .ToList();

    using (Transaction t = new Transaction(doc,”Delete Imports”))
    {
    t.Start();
    doc.Delete(toDelete);
    t.Commit();
    }
    }

    When I run it, nothing seems to happen.
    You have a beginner in the forum I’m afraid.

  3. Hi,

    Thanks again for all these macro’s they are really useful.

    I have come to a halt with the adaptive component coordinate macro. The macro ran fine. It had no errors and 4 warnings regarding a mismatch.
    I ignored this and ran the macro one my adaptive component family was in my project and selected ready to position.
    The next two emails are screen shots of the error message that displayed once I started positioning the adaptive component.

    The other email is a screen shot of the error messages.

    If you have any ideas I would appreciate it.

    Thanks again.

    Leathen Hanlon

    Sent via BlackBerry from T-Mobile

  4. Hi Harry,

    After some benchmarking the quickest solution seems to be a mix of the 2 previous ones :

    IList toDelete = new List();
    foreach (Wall ii in new FilteredElementCollector(document).OfClass(typeof(Wall)))
    {
    if (ii.IsHidden(document.ActiveView) == false)
    toDelete.Add(ii.Id);
    }

    Here are the benchmark results :
    —————————————-
    Percentage Seconds Calls Process
    —————————————-
    32.82% 12.53 3000 Sol 3
    33.37% 12.74 3000 Sol with LINQ
    33.74% 12.87 3000 Sol with Foreach
    100.00% 38.16 1 TOTAL
    —————————————-

    Regards.

    Maxime

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s