在 Solidity 中是否有一种有效的方法将字符串数组连接成单个字符串?

Ale*_*der 1 solidity

我的目标是编写一个函数,它接受一个字符串数组,并返回一个包含所有输入字符串组合的字符串。

例如,在 Python 中可以这样完成:

result = ''.join(['hello', 'solidity', 'world'])  # hellosolidityworld
Run Code Online (Sandbox Code Playgroud)

我当前的实现似乎根本没有效率:

function concat(string[] memory words) internal pure returns (string memory) {
    // calculate output length
    uint256 bytesLength;
    for (uint256 i = 0; i < words.length; i++) {
        bytesLength += bytes(words[i]).length;
    }

    bytes memory output = new bytes(bytesLength);
    uint256 currentByte;

    for (uint256 i = 0; i < words.length; i++) {
        bytes memory bytesWord = bytes(words[i]);
        for (uint256 j = 0; j < bytesWord.length; j++) {
            output[currentByte] = bytesWord[j];
            currentByte++;
        }
    }

    return string(output);
}
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?

Pet*_*jda 5

您可以通过使用abi.encodePacked()组合多个值并返回动态长度字节数组(类型bytes)来简化该函数。

由于string在 Solidity 中,其有效存储方式与字节数组相同,因此您可以轻松地将output字节数组转换为字符串。

pragma solidity ^0.8;

contract MyContract {
    function concat(string[] calldata words) external pure returns (string memory) {
        bytes memory output;

        for (uint256 i = 0; i < words.length; i++) {
            output = abi.encodePacked(output, words[i]);
        }

        return string(output);
    }
}
Run Code Online (Sandbox Code Playgroud)

["hello", " ", "world"]例如尝试一下。

  • Petr Hejda,你可以在下面看到我的回答;我已经在长字符串和长数组方面取得了相当高的效率,并且至少与这个 for 循环一样好。适用于 ReferenceTypes[] 内存和 valueType[] 内存数组 (2认同)