فهرست منبع

1. fixed get not get last column problem
2. correct bug of lettersToNumeric for mapping 'AAA1'

Daniel YC Lin 12 سال پیش
والد
کامیت
720616c87c
2فایلهای تغییر یافته به همراه17 افزوده شده و 115 حذف شده
  1. 8 49
      lib.go
  2. 9 66
      lib_test.go

+ 8 - 49
lib.go

@@ -6,7 +6,6 @@ import (
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
-	"math"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 )
 )
@@ -131,60 +130,19 @@ func getRangeFromString(rangeString string) (lower int, upper int, error error)
 	return lower, upper, error
 	return lower, upper, error
 }
 }
 
 
-// positionalLetterMultiplier gives an integer multiplier to use for a
-// position in a letter based column identifer. For example, the
-// column ID "AA" is equivalent to 26*1 + 1, "BA" is equivalent to
-// 26*2 + 1 and "ABA" is equivalent to (676 * 1)+(26 * 2)+1 or
-// ((26**2)*1)+((26**1)*2)+((26**0))*1
-func positionalLetterMultiplier(extent, pos int) int {
-	var result float64
-	var power float64
-	var offset int
-	offset = pos + 1
-	power = float64(extent - offset)
-	result = math.Pow(26, power)
-	return int(result)
-}
-
 // lettersToNumeric is used to convert a character based column
 // lettersToNumeric is used to convert a character based column
 // reference to a zero based numeric column identifier.
 // reference to a zero based numeric column identifier.
 func lettersToNumeric(letters string) int {
 func lettersToNumeric(letters string) int {
-	var sum int = 0
-	var shift int
-	extent := len(letters)
-	for i, c := range letters {
-		// Just to make life akward.  If we think of this base
-		// 26 notation as being like HEX or binary we hit a
-		// nasty little problem.  The issue is that we have no
-		// 0s and therefore A can be both a 1 and a 0.  The
-		// value range of a letter is different in the most
-		// significant position if (and only if) there is more
-		// than one positions.  For example:
-		// "A" = 0
-		//               676 | 26 | 0
-		//               ----+----+----
-		//                 0 |  0 | 0
-		//
-		//  "Z" = 25
-		//                676 | 26 | 0
-		//                ----+----+----
-		//                  0 |  0 |  25
-		//   "AA" = 26
-		//                676 | 26 | 0
-		//                ----+----+----
-		//                  0 |  1 | 0     <--- note here - the value of "A" maps to both 1 and 0.
-		if i == 0 && extent > 1 {
-			shift = 1
-		} else {
-			shift = 0
-		}
-		multiplier := positionalLetterMultiplier(extent, i)
+	sum, mul, n := 0, 1, 0
+	for i := len(letters) - 1; i >= 0; i, mul, n = i-1, mul*26, 1 {
+		c := letters[i]
 		switch {
 		switch {
 		case 'A' <= c && c <= 'Z':
 		case 'A' <= c && c <= 'Z':
-			sum += multiplier * (int((c - 'A')) + shift)
+			n += int(c - 'A')
 		case 'a' <= c && c <= 'z':
 		case 'a' <= c && c <= 'z':
-			sum += multiplier * (int((c - 'a')) + shift)
+			n += int(c - 'a')
 		}
 		}
+		sum += n * mul
 	}
 	}
 	return sum
 	return sum
 }
 }
@@ -257,7 +215,7 @@ func makeRowFromRaw(rawrow xlsxRow) *Row {
 	var cell *Cell
 	var cell *Cell
 
 
 	row = new(Row)
 	row = new(Row)
-	upper = 0
+	upper = -1
 
 
 	for _, rawcell := range rawrow.C {
 	for _, rawcell := range rawrow.C {
 		x, _, error := getCoordsFromCellIDString(rawcell.R)
 		x, _, error := getCoordsFromCellIDString(rawcell.R)
@@ -268,6 +226,7 @@ func makeRowFromRaw(rawrow xlsxRow) *Row {
 			upper = x
 			upper = x
 		}
 		}
 	}
 	}
+	upper++
 
 
 	row.Cells = make([]*Cell, upper)
 	row.Cells = make([]*Cell, upper)
 	for i := 0; i < upper; i++ {
 	for i := 0; i < upper; i++ {

+ 9 - 66
lib_test.go

@@ -83,72 +83,15 @@ func TestReadSharedStringsFromZipFile(t *testing.T) {
 }
 }
 
 
 func TestLettersToNumeric(t *testing.T) {
 func TestLettersToNumeric(t *testing.T) {
-	var input string
-	var output int
-
-	input = "A"
-	output = lettersToNumeric(input)
-	if output != 0 {
-		t.Error("Expected output 'A' == 0, but got ", strconv.Itoa(output))
-	}
-	input = "z"
-	output = lettersToNumeric(input)
-	if output != 25 {
-		t.Error("Expected output 'z' == 25, but got ", strconv.Itoa(output))
-	}
-	input = "AA"
-	output = lettersToNumeric(input)
-	if output != 26 {
-		t.Error("Expected output 'AA' == 26, but got ", strconv.Itoa(output))
-	}
-	input = "Az"
-	output = lettersToNumeric(input)
-	if output != 51 {
-		t.Error("Expected output 'Az' == 51, but got ", strconv.Itoa(output))
-	}
-	input = "BA"
-	output = lettersToNumeric(input)
-	if output != 52 {
-		t.Error("Expected output 'BA' == 52, but got ", strconv.Itoa(output))
-	}
-	input = "Bz"
-	output = lettersToNumeric(input)
-	if output != 77 {
-		t.Error("Expected output 'Bz' == 77, but got ", strconv.Itoa(output))
-	}
-	input = "AAA"
-	output = lettersToNumeric(input)
-	if output != 676 {
-		t.Error("Expected output 'AAA' == 676, but got ", strconv.Itoa(output))
-	}
-
-}
-
-func TestPositionalLetterMultiplier(t *testing.T) {
-	var output int
-	output = positionalLetterMultiplier(1, 0)
-	if output != 1 {
-		t.Error("Expected positionalLetterMultiplier(1, 0) == 1, got ", output)
-	}
-	output = positionalLetterMultiplier(2, 0)
-	if output != 26 {
-		t.Error("Expected positionalLetterMultiplier(2, 0) == 26, got ", output)
-	}
-	output = positionalLetterMultiplier(2, 1)
-	if output != 1 {
-		t.Error("Expected positionalLetterMultiplier(2, 1) == 1, got ", output)
-	}
-	output = positionalLetterMultiplier(3, 0)
-	if output != 676 {
-		t.Error("Expected positionalLetterMultiplier(3, 0) == 676, got ", output)
-	}
-	output = positionalLetterMultiplier(3, 1)
-	if output != 26 {
-		t.Error("Expected positionalLetterMultiplier(3, 1) == 26, got ", output)
-	}
-	output = positionalLetterMultiplier(3, 2)
-	if output != 1 {
-		t.Error("Expected positionalLetterMultiplier(3, 2) == 1, got ", output)
+	cases := map[string]int{"A": 0, "G": 6, "z": 25, "AA": 26, "Az": 51,
+		"BA": 52, "Bz": 77, "ZA": 26*26 + 0, "ZZ": 26*26 + 25,
+		"AAA": 26*26 + 26 + 0, "AMI": 1022}
+	for input, ans := range cases {
+		output := lettersToNumeric(input)
+		if output != ans {
+			t.Error("Expected output '"+input+"' == ", ans,
+				"but got ", strconv.Itoa(output))
+		}
 	}
 	}
 }
 }