private Cube <UValue> collapse <UValue>(Dimension dimension, Func <Group <TValue>, UValue> aggregator) { IEnumerable <Dimension> dimensions = keyLookup.Keys.Where(otherDimension => dimension != otherDimension).ToArray(); Dictionary <Key, Group <TValue> > lookup = new Dictionary <Key, Group <TValue> >(); foreach (KeyValuePair <Key, TValue> pair in valueLookup) { KeyPart oldKeyPart = pair.Key.GetKeyPart(dimension); IEnumerable <KeyPart> newKeyParts = dimensions.Select(item => pair.Key.GetKeyPart(item)); Key newKey = new Key(newKeyParts, true); Group <TValue> group; if (lookup.ContainsKey(newKey)) { group = lookup[newKey]; } else { group = new Group <TValue>(newKey); lookup.Add(newKey, group); } group.AddPair(oldKeyPart, pair.Value); } LookupBuilder <UValue> builder = new LookupBuilder <UValue>(dimensions); foreach (KeyValuePair <Key, Group <TValue> > pair in lookup) { UValue value = aggregator(pair.Value); builder.Add(pair.Key, value); } return(new Cube <UValue>(builder)); }
/// <summary> /// Creates a copy of the cube, excluding values whose keys have a matching key part value. /// </summary> /// <param name="keyPart">The dimension and key value of items to be removed.</param> /// <returns>A new cube where the values matching the key part have been removed.</returns> public Cube <TValue> Exclude(KeyPart keyPart) { if (keyPart == null) { throw new ArgumentNullException("keyPart"); } if (!keyLookup.ContainsKey(keyPart.Dimension)) { throw new ArgumentException("Cannot filter by a dimension that is not in the cube.", "dimension"); } LookupBuilder <TValue> builder = new LookupBuilder <TValue>(keyLookup.Keys); foreach (KeyValuePair <Key, TValue> pair in valueLookup) { if (!keyPart.Equals(pair.Key.GetKeyPart(keyPart.Dimension))) { builder.Add(pair.Key, pair.Value); } } return(new Cube <TValue>(builder)); }
/// <summary> /// Gets whether the given key is equal. /// </summary> /// <param name="other">The other key.</param> /// <returns>True if obj is a Key and it represents the same key; otherwise, false.</returns> public bool Equals(Key other) { if (other == null) { return(false); } foreach (KeyValuePair <Dimension, KeyPart> pair in keyParts) { Dimension dimension = pair.Key; KeyPart keyPart = pair.Value; if (!other.keyParts.ContainsKey(dimension)) { return(false); } KeyPart otherKeyPart = other.keyParts[dimension]; if (!keyPart.Equals(otherKeyPart)) { return(false); } } return(true); }
/// <summary> /// Creates a new cube where the key part value in the specified dimension equals the given key part's value. /// </summary> /// <param name="keyPart">The value the keys in the given dimension must equal.</param> /// <returns>A new cube where the keys in the specified dimension equal the given value.</returns> public Cube <TValue> Splice(KeyPart keyPart) { if (keyPart == null) { throw new ArgumentNullException("keyPart"); } if (!keyLookup.ContainsKey(keyPart.Dimension)) { throw new ArgumentException("Cannot splice a dimension that does not exist in the cube", "dimension"); } Dictionary <KeyPart, List <Key> > dimensionLookup = keyLookup[keyPart.Dimension]; LookupBuilder <TValue> builder = new LookupBuilder <TValue>(keyLookup.Keys); List <Key> keys; if (dimensionLookup.TryGetValue(keyPart, out keys)) { foreach (Key key in keys) { TValue value = valueLookup[key]; builder.Add(key, value); } } return(new Cube <TValue>(builder)); }
/// <summary> /// Creates a cube with a new dimension where all the values from the current cube are associated with the given key part value. /// </summary> /// <param name="keyPart">The dimension/key value pair to append to the cube.</param> /// <returns>A new cube with the added dimension and values.</returns> public Cube <TValue> AddDimension(KeyPart keyPart) { if (keyPart == null) { throw new ArgumentNullException("keyPart"); } if (keyLookup.ContainsKey(keyPart.Dimension)) { throw new ArgumentException("The given dimension already exists.", "dimension"); } List <Dimension> dimensions = keyLookup.Keys.ToList(); dimensions.Add(keyPart.Dimension); LookupBuilder <TValue> builder = new LookupBuilder <TValue>(dimensions); foreach (KeyValuePair <Key, TValue> pair in valueLookup) { List <KeyPart> keyParts = new List <KeyPart>(pair.Key.GetKeyParts()); keyParts.Add(keyPart); Key newKey = new Key(keyParts, true); builder.Add(newKey, pair.Value); } return(new Cube <TValue>(builder)); }