Is there a Linq method to add a single item to an IEnumerable?

后端 未结 11 636
感动是毒
感动是毒 2021-02-04 23:10

Basically I am trying to do something like this:

image.Layers

which returns an IEnumerable for all layers except the Parent layer,

相关标签:
11条回答
  • 2021-02-04 23:35

    There is no single method which does this. The closest is the Enumerable.Concat method but that tries to combine an IEnumerable<T> with another IEnumerable<T>. You can use the following to make it work with a single element

    image.Layers.Concat(new [] { image.ParentLayer });
    

    Or just add a new extension method

    public static IEnumerable<T> ConcatSingle<T>(this IEnumerable<T> enumerable, T value) {
      return enumerable.Concat(new [] { value });
    }
    
    0 讨论(0)
  • 2021-02-04 23:37

    You can use Enumerable.Concat:

    var allLayers = image.Layers.Concat(new[] {image.ParentLayer});
    
    0 讨论(0)
  • 2021-02-04 23:42

    There is the Concat method which joins two sequences.

    0 讨论(0)
  • 2021-02-04 23:48

    You can do something like:

    image.Layers.Concat(new[] { image.ParentLayer });
    

    which concats the enum with a single-element array containing the thing you want to add

    0 讨论(0)
  • 2021-02-04 23:51

    Append and Prepend have now been added to the .NET Standard framework, so you no longer need to write your own. Simply do this:

    image.Layers.Append(image.ParentLayer)
    

    See What are the 43 APIs that are in .Net Standard 2.0 but not in .Net Framework 4.6.1? for a great list of new functionality.

    0 讨论(0)
  • 2021-02-04 23:52

    Many implementations have been given already. Mine looks a bit different (but performs just as well)

    Also, I find it practicle to also have control over the ORDER. thus often, I also have a ConcatTo method, putting the new element op front.

    public static class Utility
    {
        /// <summary>
        /// Adds the specified element at the end of the IEnummerable.
        /// </summary>
        /// <typeparam name="T">The type of elements the IEnumerable contans.</typeparam>
        /// <param name="target">The target.</param>
        /// <param name="item">The item to be concatenated.</param>
        /// <returns>An IEnumerable, enumerating first the items in the existing enumerable</returns>
        public static IEnumerable<T> ConcatItem<T>(this IEnumerable<T> target, T item)
        {
            if (null == target) throw new ArgumentException(nameof(target));
            foreach (T t in target) yield return t;
            yield return item;
        }
    
        /// <summary>
        /// Inserts the specified element at the start of the IEnumerable.
        /// </summary>
        /// <typeparam name="T">The type of elements the IEnumerable contans.</typeparam>
        /// <param name="target">The IEnummerable.</param>
        /// <param name="item">The item to be concatenated.</param>
        /// <returns>An IEnumerable, enumerating first the target elements, and then the new element.</returns>
        public static IEnumerable<T> ConcatTo<T>(this IEnumerable<T> target, T item)
        {
            if (null == target) throw new ArgumentException(nameof(target));
            yield return item;
            foreach (T t in target) yield return t;
        }
    }
    

    Or alternatively, use an implicitly created array. (using the params keyword) so you can call the method to add one or more items at a time:

    public static class Utility
    {
        /// <summary>
        /// Adds the specified element at the end of the IEnummerable.
        /// </summary>
        /// <typeparam name="T">The type of elements the IEnumerable contans.</typeparam>
        /// <param name="target">The target.</param>
        /// <param name="items">The items to be concatenated.</param>
        /// <returns>An IEnumerable, enumerating first the items in the existing enumerable</returns>
        public static IEnumerable<T> ConcatItems<T>(this IEnumerable<T> target, params T[] items) =>
            (target ?? throw new ArgumentException(nameof(target))).Concat(items);
    
        /// <summary>
        /// Inserts the specified element at the start of the IEnumerable.
        /// </summary>
        /// <typeparam name="T">The type of elements the IEnumerable contans.</typeparam>
        /// <param name="target">The IEnummerable.</param>
        /// <param name="items">The items to be concatenated.</param>
        /// <returns>An IEnumerable, enumerating first the target elements, and then the new elements.</returns>
        public static IEnumerable<T> ConcatTo<T>(this IEnumerable<T> target, params T[] items) =>
            items.Concat(target ?? throw new ArgumentException(nameof(target)));
    
    0 讨论(0)
提交回复
热议问题