programing

IEnumerable에 단일 항목을 추가하는 Linq 메서드가 있습니까?

sourcetip 2021. 1. 17. 12:39
반응형

IEnumerable에 단일 항목을 추가하는 Linq 메서드가 있습니까??


기본적으로 다음과 같이 시도하고 있습니다.

image.Layers

레이어를 제외한 모든 레이어에 대해 IEnumerable을 반환 Parent하지만 경우에 따라 다음을 수행하고 싶습니다.

image.Layers.With(image.ParentLayer);

에 의해 만족되는 일반적인 사용의 100에 비해 몇 군데에서만 사용되기 때문 image.Layers입니다. 그래서 Parent레이어를 반환하는 다른 속성을 만들고 싶지 않습니다 .


한 가지 방법은 항목 (예 : 배열)에서 단일 시퀀스를 생성 한 다음 Concat원본에 배치하는 것입니다.

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

이 작업을 자주 수행하는 경우 여기나열된Append 것과 같은 (또는 유사한) 확장 방법을 작성하는 것이 좋습니다.

image.Layers.Append(image.ParentLayer)

이미 많은 구현이 제공되었습니다. 내 모습은 약간 달라 보이지만 성능도 똑같습니다.

또한 나는 ORDER를 통제하는 것이 실용적이라는 것을 알았다. 따라서 종종 ConcatTo 메서드를 사용하여 새 요소를 앞에 놓습니다.

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;
    }
}

또는 암시 적으로 생성 된 배열을 사용합니다. ( params 키워드 사용) 한 번에 하나 이상의 항목을 추가하는 메서드를 호출 할 수 있습니다.

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)));

이를 수행하는 단일 방법은 없습니다. 가장 가까운 Enumerable.Concat방법 방법이지만 IEnumerable<T>다른 IEnumerable<T>. 다음을 사용하여 단일 요소로 작동하도록 할 수 있습니다.

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

또는 새로운 확장 방법을 추가하십시오.

public static IEnumerable<T> ConcatSingle<T>(this IEnumerable<T> enumerable, T value) {
  return enumerable.Concat(new [] { value });
}

Append그리고 Prepend지금 자신을 작성하는 그래서 더 이상 필요는 .NET 표준 프레임 워크에 추가되지 않았습니다. 다음과 같이하십시오.

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.


You can use Enumerable.Concat:

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

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


I once made a nice little function for this:

public static class CoreUtil
{    
    public static IEnumerable<T> AsEnumerable<T>(params T[] items)
    {
        return items;
    }
}

Now this is possible:

image.Layers.Append(CoreUtil.AsEnumerable(image.ParentLayer, image.AnotherLayer))

If you like the syntax of .With, write it as an extension method. IEnumerable won't notice another one.


I use the following extension methods to avoid creating a useless Array:

public static IEnumerable<T> ConcatSingle<T>(this IEnumerable<T> enumerable, T value) {
   return enumerable.Concat(value.Yield());
}

public static IEnumerable<T> Yield<T>(this T item) {
    yield return item;
}

There is the Concat method which joins two sequences.


/// <summary>Concatenates elements to a sequence.</summary>
/// <typeparam name="T">The type of the elements of the input sequences.</typeparam>
/// <param name="target">The sequence to concatenate.</param>
/// <param name="items">The items to concatenate to the sequence.</param>
public static IEnumerable<T> ConcatItems<T>(this IEnumerable<T> target, params T[] items)
{
    if (items == null)
        items = new [] { default(T) };
    return target.Concat(items);
}

This solution is based on realbart's answer. I adjusted it to allow the use of a single null value as a parameter:

var newCollection = collection.ConcatItems(null)

ReferenceURL : https://stackoverflow.com/questions/4890528/is-there-a-linq-method-to-add-a-single-item-to-an-ienumerablet

반응형