Artículos correspondientes en diferentes matrices y realizar operaciones en ellas -- # campo con datetime camp codereview Relacionados El problema

Matching items in different arrays and performing operations on them


3
vote

problema

Español

Tengo una estructura de datos que utiliza un 9988776665544332 para realizar series de tiempo para diferentes productos. TimeSeries3 Se implementa como algo que sostiene una matriz de Point , que contienen un 9988776655544335 y un 9988777665544336 .

su interfaz es:

  TimeSeries{     int Length{ get; }     Point ElementAt(int index);      DateTime StartTime { get; }     DateTime EndTime { get; }         }   

Dado un par de elementos de dicha estructura de datos. Necesito encontrar la primera vez que se dividen en el que divergen. Para mi definición de divergencia, si un diccionario contiene un elemento y el otro, ¿no necesito devolver la hora del primer punto del TimeSeries

Este es el código que estoy usando para calcular la diferencia y que me gustaría que revise y comentará:

  bool TryFindFirstDivergenceTime(Dictionary<ID, TimeSeries> baseline, Dictionary<ID, TimeSeries> other, out DateTime firstDivergenceTime) {     firstDivergenceTime = default(DateTime);      foreach(var baselineIDSeriesPair in baseline)     {         if(other.ContainsKey(baselineIDSeriesPair.Key))         {             firstDivergenceTime = Min(FindFirstDivergenceTime(baselineIDSeriesPair.Value, other[baselineIDSeriesPair.Key]), firstDivergenceTime);         }         else         {             firstDivergenceTime = Min(baselineIDSeriesPair.Value.Start, firstDivergenceTime);         }     }     foreach(var otherIDSeriesPair in other)     {         if(!baseline.ContainsKey(otherIDSeriesPair.Key))         {             firstDivergenceTime = Min(otherIDSeriesPair.Value.Start, firstDivergenceTime);         }     }      return firstDivergenceTime != default(DateTime); }  public DateTime Min(DateTime first, DateTime second) {     if(first == default(DateTime))         return second;     if(second == default(DateTime))         return first;     return new DateTime(Math.Min(first.Ticks, second.Ticks)); }  DateTime FindFirstDivergenceTime(TimeSeries first, TimeSeries second) {     if(first.Length != second.Length)     {         throw new ArgumentException();     }     for(var i=0; i < first.Length; i++)     {         if(! first.ElementAt(i).Equals(second.ElementAt(i)))         {             return Min(first.ElementAt(i).Time, second.ElementAt(i).Time);         }     }     return default(DateTime); }  

Tengo la sensación de que no me estoy acercando al problema de la manera correcta, ya que el código contiene la repetición de la lógica para encontrar la hora de la primera diferencia cuando no tengo el mismo producto en ambos diccionarios. < / p>

El otro piensa que no me gusta especialmente es que me encuentro rompiendo simetría y uso para el diccionario #! /usr/bin/env python3 import random import string from itertools import zip_longest def generator(listKeys,listWords): diff = len(listKeys)-len(listWords) if diff > 0: for i in range(0,diff): listWords.append(None) elif diff<0: listWords = listWords[0:len(listKeys)] done = dict(zip(listKeys,listWords)) return done if __name__ == "__main__": listKeys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'] listWords = [94, 87, 92, 5, 75, 91, 60, 5] print("Keys more values: Keys: %s Values %s Result: %s " % (listKeys, listWords,generator(listKeys,listWords))) listKeys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'] listWords = [9, 65, 18, 80, 2, 16, 81, 98, 73, 2, 88, 30, 1, 78, 92] print("Values more keys: Keys: %s Values %s Result: %s " % (listKeys, listWords,generator(listKeys,listWords))) listKeys = [] listWords = [] for i in range(0,random.randrange(5,15)): listKeys.append(list(string.ascii_lowercase)[i]) for i in range(0,random.randrange(6,16)): listWords.append(random.randrange(0,100)) print("Random: Keys: %s Values %s Result: %s " % (listKeys, listWords,generator(listKeys,listWords))) 0 #! /usr/bin/env python3 import random import string from itertools import zip_longest def generator(listKeys,listWords): diff = len(listKeys)-len(listWords) if diff > 0: for i in range(0,diff): listWords.append(None) elif diff<0: listWords = listWords[0:len(listKeys)] done = dict(zip(listKeys,listWords)) return done if __name__ == "__main__": listKeys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'] listWords = [94, 87, 92, 5, 75, 91, 60, 5] print("Keys more values: Keys: %s Values %s Result: %s " % (listKeys, listWords,generator(listKeys,listWords))) listKeys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'] listWords = [9, 65, 18, 80, 2, 16, 81, 98, 73, 2, 88, 30, 1, 78, 92] print("Values more keys: Keys: %s Values %s Result: %s " % (listKeys, listWords,generator(listKeys,listWords))) listKeys = [] listWords = [] for i in range(0,random.randrange(5,15)): listKeys.append(list(string.ascii_lowercase)[i]) for i in range(0,random.randrange(6,16)): listWords.append(random.randrange(0,100)) print("Random: Keys: %s Values %s Result: %s " % (listKeys, listWords,generator(listKeys,listWords))) 1 de su #! /usr/bin/env python3 import random import string from itertools import zip_longest def generator(listKeys,listWords): diff = len(listKeys)-len(listWords) if diff > 0: for i in range(0,diff): listWords.append(None) elif diff<0: listWords = listWords[0:len(listKeys)] done = dict(zip(listKeys,listWords)) return done if __name__ == "__main__": listKeys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'] listWords = [94, 87, 92, 5, 75, 91, 60, 5] print("Keys more values: Keys: %s Values %s Result: %s " % (listKeys, listWords,generator(listKeys,listWords))) listKeys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'] listWords = [9, 65, 18, 80, 2, 16, 81, 98, 73, 2, 88, 30, 1, 78, 92] print("Values more keys: Keys: %s Values %s Result: %s " % (listKeys, listWords,generator(listKeys,listWords))) listKeys = [] listWords = [] for i in range(0,random.randrange(5,15)): listKeys.append(list(string.ascii_lowercase)[i]) for i in range(0,random.randrange(6,16)): listWords.append(random.randrange(0,100)) print("Random: Keys: %s Values %s Result: %s " % (listKeys, listWords,generator(listKeys,listWords))) 2 < / Código>, mientras que de la otra necesito realizar una búsqueda.

¿Cómo abordaría esos problemas?

Original en ingles

I have a data structure that uses a Dictionary<ID,TimeSeries> to hold time series for different products. TimeSeries is implemented as something holding an array of Point, which contain a DateTime and a double.

Its interface is:

TimeSeries{     int Length{ get; }     Point ElementAt(int index);      DateTime StartTime { get; }     DateTime EndTime { get; }         } 

Given a pair of elements of such data structure I need to find the first time instant where they diverge. For my definition of divergence, if a dictionary contains an element and the other doesn't I need to return the time of the first point of the TimeSeries I have.

This is the code I'm using to compute the difference and that I'd like you to review and comment:

bool TryFindFirstDivergenceTime(Dictionary<ID, TimeSeries> baseline, Dictionary<ID, TimeSeries> other, out DateTime firstDivergenceTime) {     firstDivergenceTime = default(DateTime);      foreach(var baselineIDSeriesPair in baseline)     {         if(other.ContainsKey(baselineIDSeriesPair.Key))         {             firstDivergenceTime = Min(FindFirstDivergenceTime(baselineIDSeriesPair.Value, other[baselineIDSeriesPair.Key]), firstDivergenceTime);         }         else         {             firstDivergenceTime = Min(baselineIDSeriesPair.Value.Start, firstDivergenceTime);         }     }     foreach(var otherIDSeriesPair in other)     {         if(!baseline.ContainsKey(otherIDSeriesPair.Key))         {             firstDivergenceTime = Min(otherIDSeriesPair.Value.Start, firstDivergenceTime);         }     }      return firstDivergenceTime != default(DateTime); }  public DateTime Min(DateTime first, DateTime second) {     if(first == default(DateTime))         return second;     if(second == default(DateTime))         return first;     return new DateTime(Math.Min(first.Ticks, second.Ticks)); }  DateTime FindFirstDivergenceTime(TimeSeries first, TimeSeries second) {     if(first.Length != second.Length)     {         throw new ArgumentException();     }     for(var i=0; i < first.Length; i++)     {         if(! first.ElementAt(i).Equals(second.ElementAt(i)))         {             return Min(first.ElementAt(i).Time, second.ElementAt(i).Time);         }     }     return default(DateTime); } 

I have the feeling that I am not approaching the problem in the right way as the code contains the repetition of the logic to find the time of the first difference when I don't have the same product in both the dictionaries.

The other think that I don't particularly like is that I find myself breaking th symmetry and using for on dictionary Key and Value from its IEnumerable, while from the other I need to perform a lookup.

How would you address those issues?

     
     
     

Lista de respuestas

2
 
vote
vote
La mejor respuesta
 

Antes de llegar a su pregunta sobre la reducción de la duplicación, hay otro problema que me gustaría señalar primero. El uso de default(DateTime) como cheque para la ausencia de un valor es incorrecto y engañoso. default(DateTime) es una fecha válida . Sin embargo, es poco probable que tenga una fecha que iguale ese valor, es engañoso usar porque cualquiera que vea su código que ve una variable 9988777666555544332, asumirá que tiene un valor de fecha adecuado porque em> tiene que . Como estructura, no se puede representar como null , por lo que siempre mantiene un valor. Ingrese tipos anulables . DateTime? expresa claramente que la variable puede estar en un estado donde no tiene un valor de fecha.

Dicho esto, parece que está tratando de unirse a los dos diccionarios y comparar estas formas:

  1. cuando hay llaves coincidentes.
  2. cuando solo uno de los diccionarios sostiene una clave.

Suena como un Únete al exterior completo , que Alguien ha compartido amablemente un método de extensión LINQ-ESQUE para hacerlo en desbordamiento de la pila . Usando esto, puede reescribir de manera concisa y expresiva sus métodos como para evitar la duplicación (tenga en cuenta el uso de DateTime? ):

  // Note: I think this is a bad method name (it's the same as the one below, // which I think is better suited for the name). It should probably express // the comparison between these Dictionary maps. public static DateTime? GetEarliestDivergenceTime(Dictionary<int, TimeSeries> baseline, Dictionary<int, TimeSeries> other, DateTime? defaultEarliestDivergenceTime = null) {     // Omitting 'FullOuterJoin' code in StackOverflow link:     var earliestDivergenceTimes = baseline.FullOuterJoin(         other,         b => b.Key,         o => o.Key,         (b,o) => GetEarliestDivergenceTimeOrDefault(b, o));      return earliestDivergenceTimes.Min() ?? defaultEarliestDivergenceTime; }  public static DateTime? GetEarliestDivergenceTime(TimeSeries ts1, TimeSeries ts2, DateTime? defaultEarliestDivergenceTime) {     DateTime? earliestDivergenceTime = null;      if(ts1 != null && ts2 != null)     {         // Compare.     }     else if(ts1 != null && ts2 == null)     {         // Use ts1.     }     else if(ts1 == null && ts2 != null)     {         // Use ts2.     }      // earliestDivergenceTime will be null if both t1 and t2 are null.     return earliestDivergenceTime ?? defaultEarliestDivergenceTime; }   
 

Before getting to your question about reducing the duplication, there's another issue I'd like to point out first. The use of default(DateTime) as a check for the absence of a value is incorrect and misleading. default(DateTime) is a valid date. However unlikely it is that you will have a date that equals that value, it is misleading to use because anyone looking at your code that sees a DateTime variable will assume that it holds a proper date value because it has to. As a struct, it can't be represented as null, so it always holds a value. Enter nullable types. DateTime? clearly expresses that the variable can be in a state where it doesn't hold a date value.

That said, it appears you're trying to join the two dictionary and compare in these ways:

  1. When there are matching keys.
  2. When only one of the dictionaries holds a key.

Sounds like a Full Outer Join, which someone has kindly shared a Linq-esque extension method for over on Stack Overflow. Using this, you can concisely and expressively rewrite your methods like so to avoid duplication (note the use of DateTime?):

// Note: I think this is a bad method name (it's the same as the one below, // which I think is better suited for the name). It should probably express // the comparison between these Dictionary maps. public static DateTime? GetEarliestDivergenceTime(Dictionary<int, TimeSeries> baseline, Dictionary<int, TimeSeries> other, DateTime? defaultEarliestDivergenceTime = null) {     // Omitting 'FullOuterJoin' code in StackOverflow link:     var earliestDivergenceTimes = baseline.FullOuterJoin(         other,         b => b.Key,         o => o.Key,         (b,o) => GetEarliestDivergenceTimeOrDefault(b, o));      return earliestDivergenceTimes.Min() ?? defaultEarliestDivergenceTime; }  public static DateTime? GetEarliestDivergenceTime(TimeSeries ts1, TimeSeries ts2, DateTime? defaultEarliestDivergenceTime) {     DateTime? earliestDivergenceTime = null;      if(ts1 != null && ts2 != null)     {         // Compare.     }     else if(ts1 != null && ts2 == null)     {         // Use ts1.     }     else if(ts1 == null && ts2 != null)     {         // Use ts2.     }      // earliestDivergenceTime will be null if both t1 and t2 are null.     return earliestDivergenceTime ?? defaultEarliestDivergenceTime; } 
 
 
 
 

Relacionados problema

8  Conversión de STD :: Chrono :: Time_Point to / from std :: string  ( Converting stdchronotime point to from stdstring ) 
Considere estas funciones que permitan convertir checkOnline.sh4 a / FROM checkOnline.sh5 Con un formato Fecha de fecha ". checkOnline.sh6 con uso:...

5  Método de cálculo del día del año  ( Day of year calculation method ) 
El ejercicio que quería resolver es de aquí . Copiando desde esa página: public static int dayOfYear(int month, int dayOfMonth, int year) { if (month...

6  Compara el último tiempo de modificación con tiempo especificado  ( Compare last modification time with specfied time ) 
Estoy escribiendo una función en Python que compara el tiempo de modificación de un archivo en Linux (usando OS.STAT) con un tiempo específico y compare las f...

4  Salida de una cuenta regresiva en un div  ( Outputting a countdown in a div ) 
Obtuve este código trabajando con el complemento de cuenta regresiva jQuery para tomar una entrada y salida una cadena cuenta regresiva en un div. ¿Hay una ...

0  Valor numérico para una fecha, DataTado y Datediff  ( Numeric value for a date dateadd and datediff ) 
En MS Excel, una fecha también se representa como un valor numérico, con el 1-enero-1900 como el primer día. También en VBA hay funciones de DataLTD y Datedif...

2  Obtén el primer patrimonio dado por los días de semana y un tiempo de inicio  ( Get first datetime by given weekdays and a starttime ) 
En el trabajo hay un sistema de entrada donde los clientes pueden especificar los días de semana y una hora de inicio para un evento. Los días de semana son e...

5  Representando el tiempo de apertura y cierre para un negocio  ( Representing the opening and closing time for a business ) 
Tengo una clase de openclose que solo representa las horas de operación de un negocio por la apertura y el tiempo de cierre. Toma los tiempos de apertura y ci...

10  Obteniendo la última fecha donde ocurrió un día de la semana dado  ( Getting the last date where a given week day occurred ) 
Estoy tratando de aprender un poco sobre la programación funcional y como mi herramienta, elegí F # ya que soy un desarrollador de .NET y el medio ambiente es...

10  Obteniendo tiempo actual con milisegundos  ( Getting current time with milliseconds ) 
Estoy buscando una forma más eficiente o más corta de lograr la siguiente salida utilizando el siguiente código: timeval curTime; gettimeofday(&curTime, NU...

5  Calcular el tiempo transcurrido de los tiempos de entrada sin usar declaraciones condicionales  ( Calculate elapsed time from input times without using conditional statements ) 
Acabo de empezar la programación y nos estamos enseñando C ++. Después de nuestra 2ª conferencia, nos dieron una tarea para hacer un programa que tome dos val...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos