Estoy tratando de portar un código de Python a C #.

El objetivo es comparar elementos adyacentes y ver si cuatro valores consecutivos son mayores que el uno al otro.

Después de esta publicación (Comparar dos elementos adyacentes en la misma lista) estaba capaz de usar pairwise en una deque para comparar con éxito elementos adyacentes .

//In python
from more_itertools import pairwise

for x, y in pairwise(a_deque):
    if (x < y):
        i += 1
        if (i == 4)
            print("Hello world!")

El problema es que C # no contiene la biblioteca more_itertools , por lo que actualmente estoy buscando una técnica similar para lograr la misma solución.

FYI. La implementación de deque es de https://www.nuget.org/packages/Nito. Colecciones.Deque /

¿Alguna sugerencia ?

1
xor31four 1 oct. 2019 a las 13:41

4 respuestas

La mejor respuesta

Puede implementar el método por parejas de Python usted mismo de esta manera:

public static IEnumerable<(T, T)> Pairwise<T>(IEnumerable<T> collection)
{
    using (var enumerator = collection.GetEnumerator())
    {
        enumerator.MoveNext();
        var previous = enumerator.Current;
        while (enumerator.MoveNext())
        {
            yield return (previous, enumerator.Current);
            previous = enumerator.Current;
        }
    }
}

Entonces el algoritmo en C # es estructural muy similar a la versión de Python:

static void Main(string[] args)
{
    var values = new[] { 5, 7, 8, 9, 10, 10, 8, 2, 1 };

    var i = 0;

    foreach (var (x, y) in Pairwise(values))
    {
        if (x < y)
        {
            i++;
            if (i == 4)
                Console.WriteLine("Hello world!");
        }
    }

    Console.ReadLine();
}
1
Mario Dekena 1 oct. 2019 a las 12:08

Solo crea la función:

static IEnumerable<(T, T)> PairWise<T>(IEnumerable<T> collection)
{
    var queue = new Queue<T>();

    foreach (T item in collection)
    {
        queue.Enqueue(item);

        if (queue.Count == 2)
        {
            T x = queue.Dequeue();
            T y = queue.Peek();
            yield return (x, y);
        }
    }
}

Y úsalo:

foreach ((int x, int y) in PairWise(new[] {1, 2, 3, 4, 5}))
{
    Console.WriteLine($"{x} {y}");
}
1
NightmareZ 1 oct. 2019 a las 13:51

hay un proyecto llamado MoreLINQ con extensiones inteligentes de LINQ. La mayoría de las veces, aunque el código es realmente simple gracias a la simplicidad de LINQ. Puede agregarlo como un paquete NuGet o como paquetes fuente individuales que agregan solo los operadores que desea.

Pairwise.cs implementa un operador que puede aplicar una función a pares de elementos:

int[] numbers = { 123, 456, 789 };
var result = numbers.Pairwise((a, b) => a + b);

La fuente es realmente simple: recupere un elemento y, si no hemos llegado al final, recupere otro y aplique la función:

    public static IEnumerable<TResult> Pairwise<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TSource, TResult> resultSelector)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));

        return _(); 

        IEnumerable<TResult> _()
        {
            using (var e = source.GetEnumerator())
            {
                if (!e.MoveNext())
                    yield break;

                var previous = e.Current;
                while (e.MoveNext())
                {
                    yield return resultSelector(previous, e.Current);
                    previous = e.Current;
                }
            }
        }
    }

El único "truco" es el uso de la función de iterador local llamada ... _

Puede considerar al operador Pairwise como un operador de ventana optimizado para solo 2 elementos. Hay otro operador Window que puede devolver secuencias de N elementos.

Esta expresión :

var x=Enumerable.Range(1,5).Window(3);

Produce las siguientes matrices:

{1,2,3}
{2,3,4}
{3,4,5}
1
Panagiotis Kanavos 1 oct. 2019 a las 12:49

Podrías intentarlo así:

for (int i = 0; i < arr.Length - 1; ++i)
{
    int a = arr[i];
    int b = arr[i + 1];
    Console.WriteLine($"{a} {b}");
}
-1
Manjar 1 oct. 2019 a las 11:27
58183103