Here's sample code of a solution I (quickly) came up with. It reads in the old struct values and pushes them to a new updated struct with additional members.
Pending on your array size - it might blow up the block gas limit if you try to loop through them all on deployment or even after deployment.
I'd suggest creating batch transactions to do X amount at a time to optimize gas costs.
Contract One:
pragma solidity ^0.4.23;
import "./Two.sol";
contract One {
Two two = new Two();
struct Boxv2 {
uint256 id;
bool isFull;
string name;
}
Boxv2[] public boxes;
constructor() public{
}
//test migration
function migrateBox(uint _id, string _name) public {
uint256 id;
bool isFull;
(id, isFull) = two.boxes(_id);
boxes.push(Boxv2(id, isFull, _name));
}
//test returning tuples
function getOldBox(uint _id) public view returns (uint256, bool) {
return two.boxes(_id);
}
}
Contract Two:
pragma solidity ^0.4.23;
contract Two{
struct Box {
uint256 id;
bool isFull;
}
Box[] public boxes;
constructor() public {
boxes.push(Box(0, false));
boxes.push(Box(1, true));
}
}