基于多个因素转换Javascript数组

时间:2014-06-23 09:19:07

标签: javascript arrays parsing statistics

这将是一个很长的问题,但请耐心等待,我会尝试解释它。 对于简单的统计练习,我试图读取某个数据集,但数据的格式非常奇怪。让我们从示例数据阵列开始。数据内部按8块数字组织。

[101, 103, 253, 253, 253, 102, 104, 254, 73, 32, 100, 111, 110, 39, 116, 32, 107, 110, 111, 119, 32, 119, 104, 97, 116, 32, 105, 115, 32, 32, 32, 32, 254, 254, 101, 102, 254, 254, 254, 0]

在数据文件中,有一些案例和一些变量(在这种情况下是3个变量和3个案例。案件可以看作是调查问卷的答复者)。

变量看起来像这样(只有一些值是相关的)

Variable A: Length 8 (regular number)
Variable B: Length 8 (regular number)
Variable C: Length 20 (string)

这意味着变量A将占用一个字节,变量B也将占用,变量C将占用3个字节(ceil(20/8))。

如果值介于1和251之间,我需要使用'值 - 某个偏差。在这种情况下100'

到目前为止,数据将如下:

Case 1 Variable A: 1
Case 1 Variable B: 3

但是,并非每个值都适合一个字节'。例如,变量C是一个String变量,可能有多个字节。这就是253值的来源。

253表示:'下一个8字节的块将是此变量的值'。多个值253意味着该值将有多个块。在这种情况下,我们知道变量C需要3个字节。所有这3个字节都是值253,所以我们知道在这个块之后我们需要读取3个8字节的块。

从数组的第8个元素开始,即:

[73, 32, 100, 111, 110, 39, 116, 32, 107, 110, 111, 119, 32, 119, 104, 97, 116, 32, 105, 115, 32, 32, 32, 32]

将其转换为字符串会给我们:

'我不知道什么是'

所以此时数据将是这样的:

Case 1 Variable A: 1
Case 1 Variable B: 3
Case 1 Variable C: 'I don't know what is'

之后我们继续处理数据。我们在最后253​​停了下来,所以现在还有两个数字(102和104,意思是2和4)。

此时数据将如下:

Case 1 Variable A: 1
Case 1 Variable B: 3
Case 1 Variable C: 'I don't know what is'
Case 2 Variable A: 2
Case 2 Variable B: 4

现在我们看到值为254.这意味着一个空字符串'。请注意,变量C(当前变量)长度为3个字节。我们在这个块中只剩下1个字节。所以我们需要跳过已读取的块,然后再读取两个字节。下一个块是:

[254, 254, 101, 102, 254, 254, 254, 0]

这将使Case 2 Variable C 254,254,254的值产生以下数据集:

Case 1 Variable A: 1
Case 1 Variable B: 3
Case 1 Variable C: 'I don't know what is'
Case 2 Variable A: 2
Case 2 Variable B: 4
Case 2 Variable C: ''

之后我们还有一些值要解释,制作结束数据集:

Case 1 Variable A: 1 - (101)
Case 1 Variable B: 3 - (103) 
Case 1 Variable C: 'I don't know what is' (253, 253, 253 = read 3 blocks: [73, 32, 100, 111, 110, 39, 116, 32, 107, 110, 111, 119, 32, 119, 104, 97, 116, 32, 105, 115, 32, 32, 32, 32]
Case 2 Variable A: 2 - (102)
Case 2 Variable B: 4 - (104)
Case 2 Variable C: '' - (254, 254, 254)
Case 3 Variable A: 1 - (101)
Case 3 Variable B: 2 - (102)
Case 3 Variable C: '' - (254, 254, 254)

通过头脑这样做似乎很容易。以编程方式执行此操作一直是我无法解决的问题。有没有人有任何想法?

2 个答案:

答案 0 :(得分:1)

我不清楚你是如何将C的值转换为字符串的,但是这段代码可以让你获得90%的代码:

function Reader(array){
    this.blocks = [];

    while(array.length){
        this.blocks.push(array.splice(0,8));
    }

    this._currentBlock = this.nextBlock();
}
Reader.prototype = {
    currentBlock: function(){
        if(!this._currentBlock.length){
            this._currentBlock = this.nextBlock();
        }
        return this._currentBlock;
    },
    readNext: function(count){
        count = count || 1;
        var output = [];

        while(count--){
            var value = this.currentBlock().shift();

            switch(value){
                case 253: value = this.nextBlock(); break;
                case 254: value = []; break;
                default : value = [value]; break;
            }

            output = output.concat(value);
        }

        return output;
    },
    nextBlock: function(){
        return this.blocks.shift();
    },
    peek: function(){
        return this._currentBlock[0];
    },
    buildCases: function(){
        var cases = [];

        do{
            var obj = {};
            var i = cases.length + 1;

            obj['Case ' + i + 'Variable A'] = this.readNext();
            obj['Case ' + i + 'Variable B'] = this.readNext();
            obj['Case ' + i + 'Variable C'] = this.readNext(3);

            cases.push(obj);
        }
        while(this.peek() !== 0);

        return cases;
    }
};

var reader = new Reader([101, 103, 253, 253, 253, 102, 104, 254, 73, 32, 100, 111, 110, 39, 116, 32, 107, 110, 111, 119, 32, 119, 104, 97, 116, 32, 105, 115, 32, 32, 32, 32, 254, 254, 101, 102, 254, 254, 254, 0]);
var cases = reader.buildCases();

答案 1 :(得分:0)

我认为你应该至少有3个指针:

curblock = 0; // current 8 byte block
ptr = 0; // byte in current 8 byte block
nextblock = 8; // next 8 byte block

两个函数readNumber()和readString()根据这些指针从数组中读取,当然还会更新这些指针。提示:

... 
if(ch == 253) {
    // my_tostring() must be implemented
    str += my_tostring(data.slice(nextblock, nextblock+8));
    nextblock += 8;
}

...
ptr++;
if(ptr == 8) { ptr=0; curblock=nextblock; nextblock+=8; }