From 2a29cfe16f4360ad0f0fbb213ccc0abcbb653087 Mon Sep 17 00:00:00 2001 From: Oliver Maus Date: Thu, 10 Aug 2023 15:23:32 +0200 Subject: [PATCH] Add FsRow members: `TryItem`, `ToDenseRow`, `HasCellAt`, `MinColIndex`, `MaxColIndex` Closes #61. --- src/FsSpreadsheet/FsRow.fs | 97 +++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 12 deletions(-) diff --git a/src/FsSpreadsheet/FsRow.fs b/src/FsSpreadsheet/FsRow.fs index 88620a36..77d109c0 100644 --- a/src/FsSpreadsheet/FsRow.fs +++ b/src/FsSpreadsheet/FsRow.fs @@ -24,7 +24,7 @@ type FsRow (rangeAddress : FsRangeAddress, cells : FsCellsCollection)= static member empty() = FsRow (FsRangeAddress(FsAddress(0,0),FsAddress(0,0)),FsCellsCollection()) /// - /// Create an FsRow from a given FsCellsCollection and an rowIndex. + /// Creates an FsRow from a given FsCellsCollection and an rowIndex. /// /// The appropriate range of the cells (i.e. minimum colIndex and maximum colIndex) is derived from the FsCells with the matching rowIndex. static member createAt(index, (cells : FsCellsCollection)) = @@ -51,17 +51,29 @@ type FsRow (rangeAddress : FsRangeAddress, cells : FsCellsCollection)= // ---------- /// The associated FsCells. - member self.Cells = + member this.Cells = base.Cells(cells) /// /// The index of the FsRow. /// - member self.Index - with get() = self.RangeAddress.FirstAddress.RowNumber + member this.Index + with get() = this.RangeAddress.FirstAddress.RowNumber and set(i) = - self.RangeAddress.FirstAddress.RowNumber <- i - self.RangeAddress.LastAddress.RowNumber <- i + this.RangeAddress.FirstAddress.RowNumber <- i + this.RangeAddress.LastAddress.RowNumber <- i + + /// + /// The number of the lowest column index of the FsRow where an FsCell exists. + /// + member this.MinColIndex + with get() = base.RangeAddress.FirstAddress.ColumnNumber + + /// + /// The number of the highest column index of the FsRow where an FsCell exists. + /// + member this.MaxColIndex + with get() = base.RangeAddress.LastAddress.ColumnNumber // ------- @@ -89,20 +101,50 @@ type FsRow (rangeAddress : FsRangeAddress, cells : FsCellsCollection)= /// static member getIndex (row : FsRow) = row.Index - + + /// + /// Checks if there is an FsCell at given column index. + /// + /// The number of the column where the presence of an FsCell shall be checked. + member this.HasCellAt(colIndex) = + this.Cells + |> Seq.exists (fun c -> c.ColumnNumber = colIndex) + + /// + /// Checks if there is an FsCell at given column index of a given FsRow. + /// + /// The number of the column where the presence of an FsCell shall be checked. + static member hasCellAt colIndex (row : FsRow) = + row.HasCellAt colIndex + /// - /// Returns the FsCell at columnIndex. + /// Returns the FsCell at columnIndex if it exists. Else creates an empty FsCell at that position. /// - member this.Item (columnIndex) = + member this.Item(columnIndex) = // use FsRangeBase call with colindex 1 - base.Cell(FsAddress(1,columnIndex),cells) + base.Cell(FsAddress(1,columnIndex),cells) /// - /// Returns the FsCell at the given columnIndex from an FsRow. + /// Returns the FsCell at the given columnIndex from an FsRow if it exists. Else creates an ampty FsCell at that position. /// static member item colIndex (row : FsRow) = row.Item(colIndex) + /// + /// Returns the FsCell at the given columnIndex if it exists. Else returns None. + /// + /// The number of the column where the FsCell shall be retrieved. + member this.TryItem(colIndex) = + if this.HasCellAt colIndex then Some this[colIndex] + else None + + /// + /// Returns the FsCell at the given columnIndex if it exists in the given FsRow. Else returns None. + /// + /// The number of the column where the FsCell shall be retrieved. + static member tryItem colIndex (row: FsRow) = + row.TryItem colIndex + /// /// Inserts the value at columnIndex as an FsCell. If there is an FsCell at the position, this FsCells and all the ones right to it are shifted to the right. /// @@ -123,4 +165,35 @@ type FsRow (rangeAddress : FsRangeAddress, cells : FsCellsCollection)= // TO DO (later) ///// Takes an FsCellsCollection and creates an FsRow from the given rowIndex and the cells in the FsCellsCollection that share the same rowIndex. - //static member fromCellsCollection rowIndex (cellsCollection : FsCellsCollection) = \ No newline at end of file + //static member fromCellsCollection rowIndex (cellsCollection : FsCellsCollection) = + + /// + /// Transforms the FsRow into a dense FsRow. + /// + /// FsRows are sparse by default. This means there are no FsCells present between positions with that are filled with FsCells. In dense FsRows, such "empty positions" are then filled with empty FsCells. + /// + member this.ToDenseRow() = + for i = this.MinColIndex to this.MaxColIndex do + ignore this[i] + + /// + /// Transforms the given FsRow into a dense FsRow. + /// + /// FsRows are sparse by default. This means there are no FsCells present between positions with that are filled with FsCells. In dense FsRows, such "empty positions" are then filled with empty FsCells. + /// + /// The FsRow that gets transformed into a dense FsRow. + /// This is an in-place operation. + static member toDenseRow (row : FsRow) = + row.ToDenseRow() + row + + /// + /// Takes a given FsRow and returns a new dense FsRow from it. + /// + /// FsRows are sparse by default. This means there are no FsCells present between positions with that are filled with FsCells. In dense FsRows, such "empty positions" are then filled with empty FsCells. + /// + /// The FsRow that whose copy gets transformed into a dense FsRow. + static member createDenseRowOf (row : FsRow) = + let newRow = row.Copy() + newRow.ToDenseRow() + newRow \ No newline at end of file