Ho bisogno di un algoritmo per unire più righe per i dati, dove una colonna è la colonna dell'indice e se una o più righe hanno lo stesso valore di indice unire i valori della colonna in una singola riga e infine ordinare le righe una nella colonna dell'indice .
Esempio di ASCII ART:
Starting point:
------------------------------------
| IndexCurve | Column A | Column B |
------------------------------------
| 1 | 1 | |
------------------------------------
| 2 | 5 | 5 |
------------------------------------
| 1 | | 1 |
------------------------------------
| 2 | 5 | 5 |
------------------------------------
| 3 | 1 | |
------------------------------------
Outcome:
------------------------------------
| IndexCurve | Column A | Column B |
------------------------------------
| 1 | 1 | 1 |
------------------------------------
| 2 | 5 | 5 |
------------------------------------
| 3 | 1 | |
------------------------------------
Come puoi vedere le colonne vuote sono state unite, i duplicati sono stati scartati e le righe sono state ordinate nella colonna indice. (NOTA: i valori delle colonne non devono essere aggiunti l'uno all'altro).
Ho cercato di trovare un algoritmo efficace per questo, ma finora credo di aver fallito perché penso che sia piuttosto inefficace e anche che non funzioni correttamente.
Qui ho del codice per mostrarti cosa ho attualmente, i primi pezzi di codice sono solo oggetti POCO per darti un'idea di cosa sto lavorando, ho anche incluso metodi uguali per vedere come confronto gli oggetti .
public interface IWitsmlLogCurveInfo
{
string Mnemonic { get; set; }
bool IndexCurve { get; set; }
}
public class WitsmlLogCurveInfo
{
string Mnemonic { get; set; }
bool IndexCurve { get; set; }
protected bool Equals(WitsmlLogCurveInfo other)
{
return string.Equals(Mnemonic, other.Mnemonic);
}
public override bool Equals(object obj)
{
if(ReferenceEquals(null, obj))
{
return false;
}
if(ReferenceEquals(this, obj))
{
return true;
}
if(obj.GetType() != this.GetType())
{
return false;
}
return Equals((WitsmlLogCurveInfo)obj);
}
public override int GetHashCode()
{
return (Mnemonic != null ? Mnemonic.GetHashCode() : 0);
}
}
public interface IWitsmlLogDataColumn
{
IWitsmlLogCurveInfo WitsmlLogCurveInfo { get; set; }
string Value { get; set; }
}
public class WitsmlLogDataColumn : IWitsmlLogDataColumn
{
public IWitsmlLogCurveInfo WitsmlLogCurveInfo { get; set; }
public string Value { get; set; }
protected bool Equals(WitsmlLogDataColumn other)
{
return string.Equals(Value, other.Value) && string.Equals(WitsmlLogCurveInfo, other.WitsmlLogCurveInfo);
}
public override bool Equals(object obj)
{
if(ReferenceEquals(null, obj))
{
return false;
}
if(ReferenceEquals(this, obj))
{
return true;
}
if(obj.GetType() != this.GetType())
{
return false;
}
return Equals((WitsmlLogDataColumn)obj);
}
public override int GetHashCode()
{
unchecked
{
return ((Value != null ? Value.GetHashCode() : 0) * 397) ^ (WitsmlLogCurveInfo != null ? WitsmlLogCurveInfo.GetHashCode() : 0);
}
}
}
public interface IWitsmlLogDataRow
{
IList<IWitsmlLogDataColumn> Columns { get; set; }
IWitsmlLogDataColumn GetIndexColumn();
}
public class WitsmlLogDataRow : IWitsmlLogDataRow
{
public IList<IWitsmlLogDataColumn> Columns { get; set; }
public IWitsmlLogDataColumn GetIndexColumn()
{
return Columns.SingleOrDefault(x => x.WitsmlLogCurveInfo.IndexCurve);
}
protected bool Equals(WitsmlLogDataRow other)
{
return Columns.All(x => other.Columns.Contains(x));
}
public override bool Equals(object obj)
{
if(ReferenceEquals(null, obj))
{
return false;
}
if(ReferenceEquals(this, obj))
{
return true;
}
if(obj.GetType() != this.GetType())
{
return false;
}
return Equals((WitsmlLogDataRow)obj);
}
public override int GetHashCode()
{
return (Columns != null ? Columns.GetHashCode() : 0);
}
}
public enum FrictionType
{
Annulus,
Sliding,
Rotating
}
public interface IWitsmlLogFriction
{
FrictionType Type { get; set; }
IList<IWitsmlLogDataRow> Rows { get; set; }
}
public class WitsmlLogFriction : IWitsmlLogFriction
{
public FrictionType Type { get; set; }
public IList<IWitsmlLogDataRow> Rows { get; set; }
public override string ToString()
{
return string.Format("FrictionType: {0}", Type);
}
protected bool Equals(WitsmlLogFriction other)
{
return Type == other.Type && Rows.All(x => other.Rows.Contains(x));
}
public override bool Equals(object obj)
{
if(ReferenceEquals(null, obj))
{
return false;
}
if(ReferenceEquals(this, obj))
{
return true;
}
if(obj.GetType() != this.GetType())
{
return false;
}
return Equals((WitsmlLogFriction)obj);
}
public override int GetHashCode()
{
unchecked
{
return ((int)Type * 397) ^ (Rows != null ? Rows.GetHashCode() : 0);
}
}
}
Ecco la Funzione Algoritmo stessa:
private IList<IWitsmlLogDataRow> CombineMultipleFrictionTypes(IList<WitsmlLogFriction> witsmlLogFrictions, WitsmlLogCurveInfo indexCurve)
{
if(indexCurve == null)
{
throw new NoNullAllowedException("IndexCurve can not be null!");
}
if(witsmlLogFrictions.Count == 1)
{
return witsmlLogFrictions.First().Rows;
}
WitsmlLogFriction witsmlLogFrictionA = witsmlLogFrictions.FirstOrDefault();
List<IWitsmlLogDataRow> rows = new List<IWitsmlLogDataRow>();
if (witsmlLogFrictionA == null)
{
return rows;
}
foreach(WitsmlLogFriction witsmlLogFrictionB in witsmlLogFrictions.Where(witsmlLogFriction => witsmlLogFriction.Type != witsmlLogFrictionA.Type))
{
foreach (IWitsmlLogDataRow witsmlLogDataRowA in witsmlLogFrictionA.Rows)
{
// Get index curve for row A
IWitsmlLogDataColumn indexCurveA = witsmlLogDataRowA.GetIndexColumn();
if (indexCurveA == null) continue;
IWitsmlLogDataRow tempWitsmlLogDataRowA = new WitsmlLogDataRow(witsmlLogDataRowA.Columns);
foreach(IWitsmlLogDataRow witsmlLogDataRowB in witsmlLogFrictionB.Rows)
{
// Get index curve for row B
IWitsmlLogDataColumn indexCurveB = witsmlLogDataRowB.GetIndexColumn();
if (indexCurveB == null) continue;
// Compare index curve values
if(indexCurveA.Equals(indexCurveB))
{
// Index curve values are identical, append columns from row B onto row A, except row B's index column
foreach(IWitsmlLogDataColumn column in witsmlLogDataRowB.Columns.Where(column => !column.WitsmlLogCurveInfo.Equals(indexCurve)))
{
tempWitsmlLogDataRowA.Columns.Add(column);
}
}
else
{
rows.Add(witsmlLogDataRowB);
}
}
// Add the new row
rows.Add(tempWitsmlLogDataRowA);
}
}
switch(indexCurve.IndexType)
{
case LogIndexType.datetime:
return rows.OrderBy(x => Convert.ToDateTime(x.GetIndexColumn().Value)).ToList();
default:
throw new ArgumentOutOfRangeException("indexCurve", "IndexType: " + indexCurve.IndexType + " is not supported.");
}
}
Il problema è che penso che sia piuttosto inefficace, ma potrebbe anche essere l'unico modo per farlo, e aggiunge più dati che dovrebbe. Quale sarebbe un modo migliore ed efficace per risolvere questo?