2012-02-17 9 views
5

En perl, la función de empalme devuelve una nueva matriz de elementos de una matriz existente y al mismo tiempo elimina estos elementos de la matriz existente.Empalme en colecciones

my @newarry = splice @oldarray, 0, 250; 

@newarray ahora contendrá 250 registros de @oldarray y @oldarray es 250 registros menos.

¿Existe un equivalente para las clases de colección C#, es decir, Array, List, Queue, Stack con una función similar? Hasta ahora solo he visto soluciones en las que se requieren dos pasos (return + remove).

Actualización - no existe ninguna funcionalidad por lo que han puesto en práctica un método extensio para apoyar la función de empalme:

public static List<T>Splice<T>(this List<T> Source, int Start, int Size) 
{ 
    List<T> retVal = Source.Skip(Start).Take(Size).ToList<T>(); 
    Source.RemoveRange(Start, Size); 
    return retVal; 
} 

Con la siguiente prueba Unidad - que sucede:

[TestClass] 
public class ListTest 
{ 
    [TestMethod] 
    public void ListsSplice() 
    { 
    var lst = new List<string>() { 
     "one", 
     "two", 
     "three", 
     "four", 
     "five" 
    }; 

    var newList = lst.Splice(0, 2); 

    Assert.AreEqual(newList.Count, 2); 
    Assert.AreEqual(lst.Count, 3); 

    Assert.AreEqual(newList[0], "one"); 
    Assert.AreEqual(newList[1], "two"); 

    Assert.AreEqual(lst[0], "three"); 
    Assert.AreEqual(lst[1], "four"); 
    Assert.AreEqual(lst[2], "five"); 

    } 
} 
+1

No hay equivalente directo en las clases de colección .NET. Por supuesto, puedes escribir tu propio método de ayuda que devuelve + eliminar. ¿Cómo piensas usar el método? Tal vez haya una forma más C# ish de hacerlo en lugar de tratar de llevar un patrón desde Perl. – dtb

+1

Gracias: he creado un método de extensión para agregar la función de empalme a las listas; esto también podría generalizarse para admitir IEnumerables. – SADeveloper

+0

Puede reemplazar 'Source.Skip (Start) .Take (Size) .ToList ()' por 'Source.GetRange (Start, Size)'. – Henrik

Respuesta

0

Sólo hay Stack.Pop() y Queue.Dequeue() que devolverá y eliminará un elemento pero no múltiples.

Si necesita este comportamiento, debe escribirlo en el suyo, pero tal vez simplemente puede ajustar uno de los anteriores. Pero debe definir qué sucede si el usuario define un número mayor que los elementos disponibles o un número de cero o menos.

2

Puede implementar un método de empalme con una extensión. Este método simplemente obtiene un rango (que es una copia del objeto al que se hace referencia en la lista), luego elimina los objetos de la lista.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace SpliceExample 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

      List<int> subset = numbers.Splice(3, 3); 

      Console.WriteLine(String.Join(", ", numbers)); // Prints 1, 2, 3, 7, 8, 9 
      Console.WriteLine(String.Join(", ", subset)); // Prints 4, 5, 6 

      Console.ReadLine(); 
     } 
    } 

    static class MyExtensions 
    { 
     public static List<T> Splice<T>(this List<T> list, int index, int count) 
     { 
      List<T> range = list.GetRange(index, count); 
      list.RemoveRange(index, count); 
      return range; 
     } 
    } 
} 
0

Si el número de elementos de corte y empalme es más grande que el número de elementos en una lista a continuación GetRange() y removeRange() Métodos de lanzar una excepción. La mejor solución es usar Omitir() y Tomar() y verificar Tamaño de lista:

public static class ListExtension 
    { 
     public static List<T> Splice<T>(this List<T> source, int start, int size) 
     { 
      var items = source.Skip(start).Take(size).ToList<T>(); 
      if (source.Count >= size) 
       source.RemoveRange(start, size); 
      else 
       source.Clear(); 
      return items; 
     } 
    } 
Cuestiones relacionadas