[2025_12_15] SpreadSheet에서 배열 파싱 오류

2025. 12. 15. 20:41TIL

Google Spreadsheet에서 배열 데이터 파싱하기

문제 상황

Google Spreadsheet에서 게임 데이터를 관리하는데, 하나의 셀에 배열 데이터를 넣어야 하는 경우가 생겼다. 예를 들어 "이 웨이브에 스폰할 건물 목록"을 [2001, 2001, 2101] 이런 식으로 저장해야 했다.

시도했던 방법들

시도 1: 쉼표로 구분

buildingIndexes
2001,2001,2101

→ CSV 변환 시 세 개의 열로 쪼개짐  (쉼표가 CSV 구분자)

 

시도 2: 대괄호로 감싸기

buildingIndexes
[2001,2001,2101]

→ CSV는 통과하지만 JSON 파싱 시 문자열로 인식 

 

시도 3: 세미콜론 사용

buildingIndexes
2001;2001;2101

→ CSV도 통과, 프로그램에서 배열로 파싱 가능 

해결 방법

1. 자동 배열 감지

값에 세미콜론(;) 또는 쉼표(,)가 있으면 배열로 인식한다.

 
 
csharp
private JToken ParseValueByType(string value, string type)
{
    // 배열 감지
    if (value.Contains(";") || value.Contains(","))
    {
        return ParseAutoArray(value, type);
    }

    // 단일 값 파싱
    switch (type)
    {
        case "int":
            return int.TryParse(value, out int intValue) 
                ? new JValue(intValue) 
                : new JValue(0);
        // ...
    }
}

2. 배열 파싱 구현

 
 
csharp
private JToken ParseAutoArray(string value, string type)
{
    if (string.IsNullOrEmpty(value))
        return new JArray();

    // 세미콜론 우선, 없으면 쉼표
    char separator = value.Contains(";") ? ';' : ',';
    string[] elements = value.Split(separator);
    JArray array = new JArray();

    foreach (string element in elements)
    {
        string trimmed = element.Trim();
        if (string.IsNullOrEmpty(trimmed)) continue;

        // 타입에 맞게 파싱
        JToken parsed = ParseSingleElement(trimmed, type);
        array.Add(parsed);
    }

    return array;
}

private JToken ParseSingleElement(string value, string type)
{
    switch (type.ToLower())
    {
        case "int":
            return int.TryParse(value, out int intValue) 
                ? new JValue(intValue) 
                : new JValue(0);
                
        case "float":
            return float.TryParse(value, out float floatValue) 
                ? new JValue(floatValue) 
                : new JValue(0f);
                
        case "string":
        default:
            return new JValue(value);
    }
}
```

## 동작 예시

### 정수 배열
```
Input:  "1;2;3", type = "int"
Output: [1, 2, 3]
```

### 문자열 배열
```
Input:  "apple;banana;orange", type = "string"
Output: ["apple", "banana", "orange"]
```

### 실수 배열
```
Input:  "1.5;2.7;3.2", type = "float"
Output: [1.5, 2.7, 3.2]
```

### 쉼표도 지원 (세미콜론 없을 때)
```
Input:  "10,20,30", type = "int"
Output: [10, 20, 30]
```

## Spreadsheet → JSON 전체 흐름

### Spreadsheet 입력
```
Type:   int           | string   | int
Header: buildingID    | name     | spawnIndexes
Data:   2001          | Barracks | 101;102;103

JSON 출력

 
 
json
[
  {
    "buildingID": 2001,
    "name": "Barracks",
    "spawnIndexes": [101, 102, 103]
  }
]

마주친 문제

문제 1: 쉼표 vs 세미콜론

처음엔 쉼표만 사용하려 했는데, CSV에서 쉼표가 열 구분자라 충돌했다.

해결: 세미콜론을 우선 구분자로 사용. 세미콜론이 없으면 쉼표로 fallback.

 
 
csharp
char separator = value.Contains(";") ? ';' : ',';

문제 2: 빈 요소 처리

"1;2;;3" 처럼 중간에 빈 값이 있는 경우.

해결: trim 후 빈 문자열이면 skip.

 
 
csharp
string trimmed = element.Trim();
if (string.IsNullOrEmpty(trimmed)) continue;

문제 3: 타입별 파싱 실패

"abc"를 int로 파싱하려 할 때.

해결: TryParse 실패 시 기본값(0) 사용.

 
 
csharp
return int.TryParse(value, out int intValue) 
    ? new JValue(intValue) 
    : new JValue(0);  // 기본값

Unity 사용 예시

JSON 로드

 
 
json
{
  "enemySpawnID": 4001,
  "buildingIndexes": [2001, 2001, 2101]
}

C# 클래스

 
 
csharp
public class EnemySpawnData : IData
{
    public int enemySpawnID;
    public List<int> buildingIndexes;  // 자동으로 파싱됨!
}

사용

 
 
csharp
EnemySpawnData data = DataManager.GetData<EnemySpawnData>("EnemySpawnData")[4001];

foreach (int buildingIndex in data.buildingIndexes)
{
    SpawnBuilding(buildingIndex);  // 2001, 2001, 2101 순서대로 스폰
}
```