Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
09/27/18 09:50:33 (6 years ago)
Author:
fholzing
Message:

#2904: Merged changes from trunk

Location:
branches/2904_CalculateImpacts/3.4
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/2904_CalculateImpacts/3.4

  • branches/2904_CalculateImpacts/3.4/Dataset.cs

    r15769 r16188  
    3838    protected Dataset(Dataset original, Cloner cloner)
    3939      : base(original, cloner) {
     40      // no need to clone the variable values because these can't be modified
    4041      variableValues = new Dictionary<string, IList>(original.variableValues);
    4142      variableNames = new List<string>(original.variableNames);
    4243      rows = original.rows;
    4344    }
     45
    4446    public override IDeepCloneable Clone(Cloner cloner) { return new Dataset(this, cloner); }
    4547
     
    5860    /// <param name="variableValues">The values for the variables (column-oriented storage). Values are not cloned!</param>
    5961    public Dataset(IEnumerable<string> variableNames, IEnumerable<IList> variableValues)
    60       : base() {
     62      : this(variableNames, variableValues, cloneValues: true) {
     63    }
     64
     65    protected Dataset(IEnumerable<string> variableNames, IEnumerable<IList> variableValues, bool cloneValues = false) {
    6166      Name = "-";
    62       if (!variableNames.Any()) {
     67
     68      if (variableNames.Any()) {
     69        this.variableNames = new List<string>(variableNames);
     70      } else {
    6371        this.variableNames = Enumerable.Range(0, variableValues.Count()).Select(x => "Column " + x).ToList();
    64       } else if (variableNames.Count() != variableValues.Count()) {
    65         throw new ArgumentException("Number of variable names doesn't match the number of columns of variableValues");
    66       } else if (!variableValues.All(list => list.Count == variableValues.First().Count)) {
    67         throw new ArgumentException("The number of values must be equal for every variable");
    68       } else if (variableNames.Distinct().Count() != variableNames.Count()) {
    69         var duplicateVariableNames =
    70           variableNames.GroupBy(v => v).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
    71         string message = "The dataset cannot contain duplicate variables names: " + Environment.NewLine;
    72         foreach (var duplicateVariableName in duplicateVariableNames)
    73           message += duplicateVariableName + Environment.NewLine;
    74         throw new ArgumentException(message);
    75       }
     72      }
     73      // check if the arguments are consistent (no duplicate variables, same number of rows, correct data types, ...)
     74      CheckArguments(this.variableNames, variableValues);
     75
    7676      rows = variableValues.First().Count;
    77       this.variableNames = new List<string>(variableNames);
    78       this.variableValues = new Dictionary<string, IList>(this.variableNames.Count);
    79       for (int i = 0; i < this.variableNames.Count; i++) {
    80         var variableName = this.variableNames[i];
    81         var values = variableValues.ElementAt(i);
    82 
    83         if (!IsAllowedType(values)) {
    84           throw new ArgumentException(string.Format("Unsupported type {0} for variable {1}.", GetElementType(values), variableName));
     77
     78      if (cloneValues) {
     79        this.variableValues = CloneValues(this.variableNames, variableValues);
     80      } else {
     81        this.variableValues = new Dictionary<string, IList>(this.variableNames.Count);
     82        for (int i = 0; i < this.variableNames.Count; i++) {
     83          var variableName = this.variableNames[i];
     84          var values = variableValues.ElementAt(i);
     85          this.variableValues.Add(variableName, values);
    8586        }
    86 
    87         this.variableValues.Add(variableName, values);
    8887      }
    8988    }
     
    117116
    118117    public ModifiableDataset ToModifiable() {
    119       var values = new List<IList>();
    120       foreach (var v in variableNames) {
    121         if (VariableHasType<double>(v)) {
    122           values.Add(new List<double>((IList<double>)variableValues[v]));
    123         } else if (VariableHasType<string>(v)) {
    124           values.Add(new List<string>((IList<string>)variableValues[v]));
    125         } else if (VariableHasType<DateTime>(v)) {
    126           values.Add(new List<DateTime>((IList<DateTime>)variableValues[v]));
    127         } else {
    128           throw new ArgumentException("Unknown variable type.");
    129         }
    130       }
    131       return new ModifiableDataset(variableNames, values);
     118      return new ModifiableDataset(variableNames, variableNames.Select(v => variableValues[v]), true);
    132119    }
    133120
     
    142129    }
    143130
    144     protected Dataset(Dataset dataset) : this(dataset.variableNames, dataset.variableValues.Values) { }
     131
    145132
    146133    #region Backwards compatible code, remove with 3.5
     
    238225      return new ReadOnlyCollection<DateTime>(values);
    239226    }
    240 
    241 
    242227    private IEnumerable<T> GetValues<T>(string variableName, IEnumerable<int> rows) {
    243228      var values = GetValues<T>(variableName);
     
    255240      return variableValues[variableName] is IList<T>;
    256241    }
    257 
    258242    protected Type GetVariableType(string variableName) {
    259243      IList list;
     
    263247      return GetElementType(list);
    264248    }
    265 
    266     protected Type GetElementType(IList list) {
     249    protected static Type GetElementType(IList list) {
    267250      var type = list.GetType();
    268251      return type.IsGenericType ? type.GetGenericArguments()[0] : type.GetElementType();
    269252    }
    270 
    271     protected bool IsAllowedType(IList list) {
     253    protected static bool IsAllowedType(IList list) {
    272254      var type = GetElementType(list);
    273255      return IsAllowedType(type);
    274256    }
    275 
    276     protected bool IsAllowedType(Type type) {
     257    protected static bool IsAllowedType(Type type) {
    277258      return type == typeof(double) || type == typeof(string) || type == typeof(DateTime);
     259    }
     260
     261    protected static void CheckArguments(IEnumerable<string> variableNames, IEnumerable<IList> variableValues) {
     262      if (variableNames.Count() != variableValues.Count()) {
     263        throw new ArgumentException("Number of variable names doesn't match the number of columns of variableValues");
     264      } else if (!variableValues.All(list => list.Count == variableValues.First().Count)) {
     265        throw new ArgumentException("The number of values must be equal for every variable");
     266      } else if (variableNames.Distinct().Count() != variableNames.Count()) {
     267        var duplicateVariableNames =
     268          variableNames.GroupBy(v => v).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
     269        string message = "The dataset cannot contain duplicate variables names: " + Environment.NewLine;
     270        foreach (var duplicateVariableName in duplicateVariableNames)
     271          message += duplicateVariableName + Environment.NewLine;
     272        throw new ArgumentException(message);
     273      }
     274      // check if all the variables are supported
     275      foreach (var t in variableNames.Zip(variableValues, Tuple.Create)) {
     276        var variableName = t.Item1;
     277        var values = t.Item2;
     278
     279        if (!IsAllowedType(values)) {
     280          throw new ArgumentException(string.Format("Unsupported type {0} for variable {1}.", GetElementType(values), variableName));
     281        }
     282      }
     283    }
     284
     285    protected static Dictionary<string, IList> CloneValues(Dictionary<string, IList> variableValues) {
     286      return variableValues.ToDictionary(x => x.Key, x => CloneValues(x.Value));
     287    }
     288
     289    protected static Dictionary<string, IList> CloneValues(IEnumerable<string> variableNames, IEnumerable<IList> variableValues) {
     290      return variableNames.Zip(variableValues, Tuple.Create).ToDictionary(x => x.Item1, x => CloneValues(x.Item2));
     291    }
     292
     293    protected static IList CloneValues(IList values) {
     294      var doubleValues = values as IList<double>;
     295      if (doubleValues != null) return new List<double>(doubleValues);
     296
     297      var stringValues = values as IList<string>;
     298      if (stringValues != null) return new List<string>(stringValues);
     299
     300      var dateTimeValues = values as IList<DateTime>;
     301      if (dateTimeValues != null) return new List<DateTime>(dateTimeValues);
     302
     303      throw new ArgumentException(string.Format("Unsupported variable type {0}.", GetElementType(values)));
    278304    }
    279305
    280306    #region IStringConvertibleMatrix Members
    281307    [Storable]
    282     protected int rows;
     308    private int rows;
    283309    public int Rows {
    284310      get { return rows; }
     311      protected set { rows = value; }
    285312    }
    286313    int IStringConvertibleMatrix.Rows {
Note: See TracChangeset for help on using the changeset viewer.