filterByColumn filters rows based on column value using the provided options. It returns a new buffer containing the filtered rows.
(colIndex int, options FilterOptions)
| 793 | // filterByColumn filters rows based on column value using the provided options. |
| 794 | // It returns a new buffer containing the filtered rows. |
| 795 | func (b *Buffer) filterByColumn(colIndex int, options FilterOptions) *Buffer { |
| 796 | b.mu.RLock() |
| 797 | defer b.mu.RUnlock() |
| 798 | |
| 799 | filtered := createNewBuffer() |
| 800 | filtered.sep = b.sep |
| 801 | filtered.colLen = b.colLen |
| 802 | filtered.rowFreeze = b.rowFreeze |
| 803 | filtered.colFreeze = b.colFreeze |
| 804 | filtered.colType = make([]int, len(b.colType)) |
| 805 | copy(filtered.colType, b.colType) |
| 806 | |
| 807 | // Pre-allocate with estimated capacity (assume ~25% match rate) |
| 808 | estimatedCapacity := (b.rowLen - b.rowFreeze) / 4 |
| 809 | if estimatedCapacity < 100 { |
| 810 | estimatedCapacity = 100 |
| 811 | } |
| 812 | filtered.cont = make([][]string, 0, estimatedCapacity) |
| 813 | |
| 814 | // Add header row if present |
| 815 | if b.rowFreeze > 0 && b.rowLen > 0 { |
| 816 | filtered.cont = append(filtered.cont, b.cont[0]) |
| 817 | filtered.rowLen = 1 |
| 818 | } |
| 819 | |
| 820 | // Early exit if column index is invalid - but still return buffer with header |
| 821 | if colIndex >= b.colLen { |
| 822 | return filtered |
| 823 | } |
| 824 | |
| 825 | // Get column type for numeric comparisons |
| 826 | colType := colTypeStr |
| 827 | if colIndex < len(b.colType) { |
| 828 | colType = b.colType[colIndex] |
| 829 | } |
| 830 | |
| 831 | // Filter data rows |
| 832 | startRow := b.rowFreeze |
| 833 | for i := startRow; i < b.rowLen; i++ { |
| 834 | if colIndex >= len(b.cont[i]) { |
| 835 | continue |
| 836 | } |
| 837 | |
| 838 | cellValue := b.cont[i][colIndex] |
| 839 | |
| 840 | // Evaluate filter condition |
| 841 | if evaluateFilter(cellValue, options, colType) { |
| 842 | filtered.cont = append(filtered.cont, b.cont[i]) |
| 843 | filtered.rowLen++ |
| 844 | } |
| 845 | } |
| 846 | |
| 847 | return filtered |
| 848 | } |
| 849 | |
| 850 | // evaluateFilter checks if a cell value matches the filter query based on the operator. |
| 851 | func evaluateFilter(cellValue string, options FilterOptions, colType int) bool { |