1

我正在嘗試創建用於在實踐中註冊學生協議的Google表單。每個協議都被註冊並獲得格式爲本年度數字的協議編號 - 今年協議的T編號/ M。例如現在它是17-T-11/M。目前協議的數量是由負責實踐的人員編寫的。 這裏是下面的腳本代碼:如何使用混合(字母和數字)元素以自然順序對數組元素進行排序

function onChange(e) 
{ 
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[1]; 
    var range = sheet.getDataRange(); 
    var values = range.getValues(); 
    var comboValues = ['16-T-105/M']; 

    // removing titles from 0 column and 1 line (titles) 
    for (var i = 1; i <= values.length; i++) { 
    var v = values[i] && values[i][0]; 
    v && comboValues.push(v) 
    } 

    // Sort the values 
    comboValues.sort(
    function(a, b) { 
     if (b.toLowerCase() < a.toLowerCase()) return -1; 
     if (b.toLowerCase() > a.toLowerCase()) return 1; 
     return 0; 
    } 
); 
    Logger.log(comboValues); 

    // google-form modification 
    var form = FormApp.openById('1SHgVIosoE34m9cny9EQySljvgnRpzffdFEZe-kzNOzA'); 

    var items = form.getItems(); 
    for (i = 4; i < items.length; i++) { 
    Logger.log("ID: " + items[i].getId(), ': ' + items[i].getType()); 
    } 

    form.getItemById('2087613006').asListItem().setChoiceValues(comboValues); 

我有問題,它與字典順序有關。註冊協議從最後登錄協議號碼選擇的人:我試着做最後登錄協議號碼總是在列表頂部。當我開始這一切時,一切都很順利(從16-T-105/M開始),但新的一年到來,在17-T-10/M協議登記後不久,我就有了問題,那17-T-10/M不在列表首位。很快我意識到發生這種情況是因爲腳本使用了字典順序,並且「認爲」2超過了10個。所以我明白,我不知何故將不得不改變這個順序,並且做到2小於10,11小於101等等上。 我的問題是如何做到這一點?我想我需要按自然順序排列數組元素 - 但我不知道如何做到這一點。 我嘗試谷歌如何做到這一點,但結果並不令人滿意 - 也許我的編碼知識相當有限(我是心理學的博士生,而不是信息學):) 也許有人會幫助如何解決這個問題。

更新: 鏈接到電子表格:https://docs.google.com/spreadsheets/d/1FH5qYTrLUNI2SCrcaqlwgu8lzAylaTkZsiALg0zIpCM/edit#gid=1620956794

鏈接到谷歌形式(實際形式的副本):https://docs.google.com/forms/d/e/1FAIpQLSerJfkv1dgHexUwxppXNyhb46twOZgvEMOIVXSOJoED3SLmyQ/viewform

+1

你能向我們展示樣品表嗎?一個是最新的表格。二是你的腳本改變了一張表。這是你不想要的工作表。最後一張是你想要的一張。這些樣本表將有助於那些認爲解決方案的人。 – Tanaike

+0

你應該用零填充。除非您遷移它,否則太晚了。否則,你需要編寫一個自定義的排序功能(如果去那條路線,向我們展示你的嘗試)。自定義排序將需要了解您的確切格式,並手動比較每個部分,或填充然後只是進行比較。 16-T-3填充將是16-T-0003等 –

回答

1

您應該調整排序方法,考慮到數據的特殊性。這裏有一種方法:函數splitConvert處理每個字符串,將其拆分爲非單詞字符,然後轉換可以轉換爲整數(並將其餘部分壓縮)。然後比較一個接一個地通過這個數組。

comboValues.sort(
    function(a, b) { 
    var as = splitConvert(a); 
    var bs = splitConvert(b); 
    for (var i = 0; i < as.length; i++) { 
     if (bs[i] < as[i]) return -1; 
     if (bs[i] > as[i]) return 1; 
    } 
    return 0; 
    } 
); 

function splitConvert(str) { 
    return str.split(/\W/).map(function(part) { 
    var x = parseInt(part, 10); 
    return isNaN(x) ? part.toLowerCase() : x; 
    }); 
} 

這不是最具性能的解決方案:split-parse函數將被重複調用相同的字符串,因爲它們正在排序。如果這成爲一個問題(我真的不這麼認爲),可以通過一次轉換來優化,創建一個數組數組,然後對其進行排序。

相關問題