// Take a single column and split it into multiple. internal void CreateColumnFromSplit <T>(Func <Row, T> fpSplit) where T : IColumnSet, new() { T dummy = new T(); string[] fields = dummy.GetFields(); // Allocate new columns Column[] newColumns = new Column[fields.Length]; for (int i = 0; i < fields.Length; i++) { newColumns[i] = new Column(fields[i], this.NumRows); this.AddColumnLast(newColumns[i]); } // Apply splitter function int rows = this.NumRows; for (int r = 0; r < rows; r++) { Row row = new RowInMemory(this, r); var result = fpSplit(row); // Place results into new columns for (int i = 0; i < fields.Length; i++) { newColumns[i].Values[r] = result.GetValue(i); } } }
/// <summary> /// Only keep rows where the predicate returns true /// </summary> /// <param name="predicate">predicate to execute on each row</param> public void KeepRows(Func <Row, bool> predicate) { if (predicate == null) { throw new ArgumentNullException("predicate"); } // Want to avoid multiple memory allocations List <int> index = new List <int>(); // take a first pass through to evaluate the predicate and track // which rows to keep int rows = this.NumRows; for (int r = 0; r < rows; r++) { Row row = new RowInMemory(this, r); bool keep = predicate(row); if (keep) { index.Add(r); } } int rows2 = index.Count; // new number of rows. int numColumns = this.Columns.Length; // Now allocate the new columns lengths var columns = new Column[numColumns]; for (int i = 0; i < numColumns; i++) { columns[i] = new Column(this.Columns[i].Name, rows2); } // Copy the the rows we decided to keep. for (int r = 0; r < rows2; r++) { int rOld = index[r]; for (int i = 0; i < numColumns; i++) { columns[i].Values[r] = this.Columns[i].Values[rOld]; } } this.Columns = columns; Utility.Assert(this.NumRows == rows2); }