C# でリスト系をシャローコピーしたい
◆ .ToList()
リストでシャッフルしたり要素入れ替えたりなどするときに 元のものは維持してコピーした新しい方でシャッフルとかしたいってことはよくありますよね
なのでシャローコピー(1階層目だけコピー)する方法を探してました
JavaScript でいうなら .slice() です
なにもしないと arr も返り値だけじゃなくて arr も変わってしまいますが .slice() でコピーした方を使うと
arr の方はそのままです
同じように考えると 部分配列を全範囲で作ればよさそうです
ということは .Skip(0) ?
でもこれだけだとリストになっていない 遅延評価のあとでするよ状態だから .Skip(0).ToList() になります
これだと list まで変わるから
これで list は変化なし!
ここでふと思ったことが
.ToList() って新しくリストを作ってるんだから Skip なんてしなくても ToList だけでいけるんじゃないの?
やってみると
ToList だけでいけました!
なのでシャローコピー(1階層目だけコピー)する方法を探してました
JavaScript でいうなら .slice() です
function swap(arr, a, b){
const w = arr[a]
arr[a] = arr[b]
arr[b] = w
return arr
}
var arr = [1, 2, 3]
swap(arr, 0, 2)
// [3, 2, 1]
arr
// [3, 2, 1]
const w = arr[a]
arr[a] = arr[b]
arr[b] = w
return arr
}
var arr = [1, 2, 3]
swap(arr, 0, 2)
// [3, 2, 1]
arr
// [3, 2, 1]
なにもしないと arr も返り値だけじゃなくて arr も変わってしまいますが .slice() でコピーした方を使うと
var arr = [1, 2, 3]
swap(arr.slice(), 0, 2)
// [3, 2, 1]
arr
// [1, 2, 3]
swap(arr.slice(), 0, 2)
// [3, 2, 1]
arr
// [1, 2, 3]
arr の方はそのままです
同じように考えると 部分配列を全範囲で作ればよさそうです
ということは .Skip(0) ?
でもこれだけだとリストになっていない 遅延評価のあとでするよ状態だから .Skip(0).ToList() になります
List<T> swap<T>(List<T> list, int a, int b) {
var w = list[a];
list[a] = list[b];
list[b] = w;
return list;
}
var list = new List<int> { 1, 2, 3 };
swap(list, 0, 2)
// List<int>(3) { 3, 2, 1 }
list
// List<int>(3) { 3, 2, 1 }
var w = list[a];
list[a] = list[b];
list[b] = w;
return list;
}
var list = new List<int> { 1, 2, 3 };
swap(list, 0, 2)
// List<int>(3) { 3, 2, 1 }
list
// List<int>(3) { 3, 2, 1 }
これだと list まで変わるから
var list = new List<int> { 1, 2, 3 };
swap(list.Skip(0).ToList(), 0, 2)
// List<int>(3) { 3, 2, 1 }
list
// List<int>(3) { 1, 2, 3 }
swap(list.Skip(0).ToList(), 0, 2)
// List<int>(3) { 3, 2, 1 }
list
// List<int>(3) { 1, 2, 3 }
これで list は変化なし!
ここでふと思ったことが
.ToList() って新しくリストを作ってるんだから Skip なんてしなくても ToList だけでいけるんじゃないの?
やってみると
var list = new List<int> { 1, 2, 3 };
swap(list.ToList(), 0, 2)
// List<int>(3) { 3, 2, 1 }
list
// List<int>(3) { 1, 2, 3 }
swap(list.ToList(), 0, 2)
// List<int>(3) { 3, 2, 1 }
list
// List<int>(3) { 1, 2, 3 }
ToList だけでいけました!