【问题标题】:how to convert an array to the shortest string possible如何将数组转换为可能的最短字符串
【发布时间】:2016-11-03 03:07:28
【问题描述】:

我有以下数组(我正在使用 JavaScript):

var arr = [2, 0, 0, 0, 12]

(数组的每个元素可以在015之间。长度是固定的,5个元素。)

我想将此数组转换为可能的最短字符串。我的实际解决方案是将其转换为十六进制(base16)字符串:

var str = '2000c'

有没有更好的解决方案? (我正在寻找 JavaScript 中的解决方案,如果可能的话没有任何库)

【问题讨论】:

  • 你的意思是十六进制(base16)?
  • 将数组编码为字符串是什么意思?
  • 你是如何编码的?添加数字等?
  • @Simon 是的可能
  • 您需要更紧凑的 0 ... 16^5-1 编码吗?

标签: javascript hex base64 base


【解决方案1】:

您可以使用toString(base) 将基数为 10 的数字转换为所需的基数。例如,十六进制(基数 16)

function encode(input){
    var encoded = input.map(function(num){
       return num.toString(16);
    }).join('');
    return encoded;
}

输出:

>encode([2, 0, 0, 0, 12]);

'2000c'

【讨论】:

  • 如果你要写一个'setter',你也可以提供一个'getter',演示:JS Fiddle
  • @DavidThomas 太好了。我实际上写了OP要求的内容。顺便谢谢
  • 你做到了,我知道 - 对不起,如果我的评论措辞不好 - 这实际上只是我认为可能有用的礼物,如果包含在答案中,而不是任何形式的批评。 :)
  • @DavidThomas David,我不会说英语,所以如果从我的评论来看,我似乎很生气/被冒犯了,不,不是。非常感谢您的努力。事件,如果你想添加,添加答案或编辑我的。
  • 我不知道谁对我的答案投了反对票。据我所知,它工作得很好
【解决方案2】:

您的输入是 5 * 4 位 = 20 位。您可以将数组重新编码为 3 个字符的字符串(24 位,实际有效负载为 20 位)并使用 btoa() 对其进行编码以生成 4 个字符的可打印字符串。

function pack(arr) {
  return btoa(
    String.fromCharCode(
      (arr[1] << 4) | arr[0],
      (arr[3] << 4) | arr[2],
      arr[4]
    )
  );
}

var packed = pack([2, 0, 0, 0, 12]);

console.log(packed); // output: 'AgAM'

解包函数将使用 atob() 并像这样重建原始数组:

function unpack(packed) {
  var str = atob(packed);
  
  return [
    str.charCodeAt(0) & 0xf,
    str.charCodeAt(0) >> 4,
    str.charCodeAt(1) & 0xf,
    str.charCodeAt(1) >> 4,
    str.charCodeAt(2)
  ];
}

var unpacked = unpack('AgAM');

console.log(unpacked); // output: [ 2, 0, 0, 0, 12 ]

【讨论】:

  • 你得到的东西真的很有趣@Arnauld,如果我的数组有固定长度的 24 个元素,它也会工作吗?
  • 这个概念,您必须将其调整为 12 个字符。每两个值存储在一个字符中,具有上半部分和下半部分。您可以通过将 atob 写入每个索引的循环中将其扩展为 N 个元素,将其打包成一个 ceil(N/2) 字符数组。
  • @DanielB。是正确的。它实际上可以很好地处理 24 个元素,因为 Base64 正在处理 3 字节数据包,而您将恰好有 24 * 4 = 96 位 = 12 字节 = 4 个 3 字节数据包。 (当然,对于更大的数组,您应该考虑使用循环而不是我使用的单片代码。)
  • @julesbou 请注意,此解决方案可为您提供最短的可打印字符长度。您也可以将其保留为 3 个字节而不将其转换为 base64。
  • @Simon 的意思——我认为——你可以删除这个 btoa() 并直接将三个 String.fromCharCode() 的串联分配给“打包”。根据输入,您将获得一个可能包含或不包含不可打印字符的字符串。如果您的目标是在运行时将其存储在一个变量中,那就太好了。但是你可能无法在源代码中包含这样的字符串——至少不能在不转义不可打印字符的情况下,从而失去短格式的好处。
猜你喜欢
  • 2016-02-03
  • 1970-01-01
  • 2013-03-26
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多