随机数组元素总是缺少元素 0

时间:2021-02-01 09:15:18

标签: javascript arrays json

我有将 excel 文件加载到 JavaScript 数组中的代码。

function Upload() {
        //Reference the FileUpload element.
        var fileUpload = document.getElementById("fileUpload");
 
        //Validate whether File is valid Excel file.
        var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.xls|.xlsx)$/;
        if (regex.test(fileUpload.value.toLowerCase())) {
            if (typeof (FileReader) != "undefined") {
                var reader = new FileReader();
 
                //For Browsers other than IE.
                if (reader.readAsBinaryString) {
                    reader.onload = function (e) {
                        ProcessExcel(e.target.result);
                    };
                    reader.readAsBinaryString(fileUpload.files[0]);
                } else {
                    //For IE Browser.
                    reader.onload = function (e) {
                        var data = "";
                        var bytes = new Uint8Array(e.target.result);
                        for (var i = 0; i < bytes.byteLength; i++) {
                            data += String.fromCharCode(bytes[i]);
                        }
                        ProcessExcel(data);
                    };
                    reader.readAsArrayBuffer(fileUpload.files[0]);
                }
            } else {
                alert("This browser does not support HTML5.");
            }
        } else {
            alert("Please upload a valid Excel file.");
        }
    };
    function ProcessExcel(data) {
        //Read the Excel File data.
        var workbook = XLSX.read(data, {
            type: 'binary'
        });
 
        //Fetch the name of First Sheet.
        var firstSheet = workbook.SheetNames[0];
 
        //Read all rows from First Sheet into an JSON array.
        excelRows = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[firstSheet]);
                localStorage["excelRows"] = JSON.stringify(excelRows);
                window.open("main screen.html", "Badge Draw - game");

    };

每次单击按钮时,数组都会随机化,并在标签中显示位于 [0] 处的元素。到目前为止一切顺利。

    //load the file into array
    memberDetails = JSON.parse(localStorage["excelRows"]);
    
    
    //randomise the array
    for (let i = memberDetails.length - 1; i >= 0; i--) {
         const j = Math.floor(Math.random() * i);
         const temp = memberDetails[i];
         memberDetails[i] = memberDetails[j];
         memberDetails[j] = temp;
     }

    //get the values stored at index 0
    memberNumber = memberDetails[0].Badge;
    memberName = memberDetails[0].Name;
     
    memberNumberLabel = document.createElement("label");
    var memberNumberText = document.createTextNode(memberNumber);
    memberNumberLabel.id = "memberNumber";
    memberNumberLabel.appendChild(memberNumberText);
    document.body.appendChild(memberNumberLabel);
    document.getElementById("memberNumber").setAttribute("style", "color: #000000; font-size: XXX-large; font-weight: bold; position: fixed; left: 40%; top: 40%");

    memberNameLabel = document.createElement("label");
    var memberNameText = document.createTextNode(memberName);
    memberNameLabel.id = "memberName";
    memberNameLabel.appendChild(memberNameText);
    document.body.appendChild(memberNameLabel);
    document.getElementById("memberName").setAttribute("style", "color: #000000; font-size: xxx-large; font-weight: bold; position: fixed; left: 40%; top: 60%");

}

数组中只有 6 个元素(测试)。但是,经过数百次测试后,我注意到,在随机化之前位于 [0] 的元素从未出现过。我可以打印数组并且所有元素都存在,但是,我永远不能调用元素 [0]。

我确定这是一个逻辑错误,但我无法调试。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您正在使用

改组数组
for (let i = memberDetails.length - 1; i >= 0; i--) {
    const j = Math.floor(Math.random() * i);
    const temp = memberDetails[i];
    memberDetails[i] = memberDetails[j];
    memberDetails[j] = temp;
}

要查看逻辑问题,请考虑一个只有 2 个元素的数组,然后空运行循环。我们将从 1 迭代到 0。

当 i 为 1 时,Math.random() * i 会返回一个介于 0 和 1 之间的值,但由于我们正在执行 Math.floor(),因此它总是将其取整为 0(因为 Math.random() 从不返回 1 )。然后我们将第 0 个元素与第 1 个元素交换。

当 i 为 0 时,Math.random() * i 为 0,因此我们将现在的第 0 个元素与其自身交换。

这是逻辑错误,您可能需要将 floor 替换为 round

但是!

如果您只想从数组中随机选择一个元素,就足够了

const randomMember = memberDetails[Math.floor(Math.random() * memberDetails.length]

而不是打乱整个数组。