Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Swift vs. C#: Collection Types

More than 5 years have passed since last update.

Collection Types

Swift:

  1. Array(ordered lists of values of the same type)
  2. Dictionary(unordered collections of values of the same type)

C#:

  1. System.Collections
  2. System.Collections.Generic
  3. System.Collections.Concurrent
  4. System.Collections.Specialized
  5. System.Collections.Immutable

Mutability of Collections

  • Mutable & Immutable (Swift/C#)
  1> var mutable: [String] = ["Cat", "Dog"]
mutable: [String] = 2 values {
  [0] = "Cat"
  [1] = "Dog"
}
  2> mutable[0] = "Mouse"
  3> mutable
$R0: [String] = 2 values {
  [0] = "Mouse"
  [1] = "Dog"
}
  4> let immutable: [String] = mutable
immutable: [String] = 2 values {
  [0] = "Mouse"
  [1] = "Dog"
}
  5> immutable[0] = "Pig"
/var/folders/3n/0lk686q1129clzkw38blpwdc0000gp/T/lldb/9119/repl9.swift:2:1: error: '@lvalue $T5' is not identical to 'String'
immutable[0] = "Pig"
^

  • var宣言しないとimmutable(それはそうか)
 15> Array<Int>().append(0)
/var/folders/3n/0lk686q1129clzkw38blpwdc0000gp/T/lldb/9119/repl31.swift:2:1: error: immutable value of type 'Array<Int>' only has mutating members named 'append'
Array<Int>().append(0)
^            ~~~~~~

csharp> var mutable = new List<string>{ "Cat", "Dog" };
csharp> mutable
{ "Cat", "Dog" }
csharp> mutable[0] = "Mouse";
csharp> mutable
{ "Mouse", "Dog" }
csharp> var immutable = mutable.AsReadOnly();     
csharp> immutable
{ "Mouse", "Dog" }
csharp> immutable[0] = "Pig";
(1,11): error CS0200: Property or indexer `System.Collections.ObjectModel.ReadOnlyCollection<string>.this[int]' cannot be assigned to (it is read-only)
  • readonly しても mutable
csharp> class Animal { public readonly static List<string> Animals = new List<string>{"Cat", "Dog"};};  
csharp> Animal.Animals
{ "Cat", "Dog" }
csharp> Animal.Animals[0] = "Pig";
csharp> Animal.Animals  
{ "Pig", "Dog" }
  • ただし readonly なので
csharp> Animal.Animals = new List<string>();
(1,9): error CS0198: A static readonly field `Animal.Animals' cannot be assigned to (except in a static constructor or a variable initializer)
  • ReadOnlyCollection型で宣言
csharp> using System.Collections.ObjectModel;
csharp> class Animal { public static ReadOnlyCollection<string> Animals = new List<string>{"Cat", "Dog"}.AsReadOnly();};  
csharp> Animal.Animals[0] = "Pig"
(1,16): error CS0200: Property or indexer `System.Collections.ObjectModel.ReadOnlyCollection<string>.this[int]' cannot be assigned to (it is read-only)

Arrays

Array Type Shorthand Syntax

  5> var a : Array<String> = ["Cat", "Dog"]
a: [String] = 2 values {
  [0] = "Cat"
  [1] = "Dog"
}
  6> var a : [String] = ["Cat", "Dog"]
a: [String] = 2 values {
  [0] = "Cat"
  [1] = "Dog"
}
  • C# : 短縮系は無いと思う

Array Literals

  7> [1, 2, 3]
$R1: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
  9> ["Apple", "Oragnge"]
$R3: [String] = 2 values {
  [0] = "Apple"
  [1] = "Oragnge"
}
  • C# : リテラルとかない。コンストラクタ必須
csharp> new int[]{1, 2, 3};
{ 1, 2, 3 }

Accessing and Modifying an Array

 10> var a: [String]
a: [String] = 0 values
 11> a.isEmpty
$R4: Bool = true

 12> a.count
$R5: Int = 0
csharp> (new string[]{}).Length == 0
true
 19> var a: [String]
a: [String] = 0 values
 20> a.append("Dog")
 21> a
$R9: [String] = 1 value {
  [0] = "Dog"
}
csharp> var a = new List<string>{};
csharp> a.Add("Dog");
csharp> a
{ "Dog" }
 22> a += ["Cat", "Pig"]
 23> a
$R10: [String] = 3 values {
  [0] = "Dog"
  [1] = "Cat"
  [2] = "Pig"
}
csharp> a.Concat(new List<string>{"Cat", "Pig"});
{ "Dog", "Cat", "Pig" }
csharp> a
{ "Dog" }

csharp> a += new List<string>{"Cat", "Pig"};  
(1,2): error CS0019: Operator `+=' cannot be applied to operands of type `System.Collections.Generic.List<string>' and `System.Collections.Generic.List<string>'

 25> var a = Array(1...5)
a: [Int] = 5 values {
  [0] = 1
  [1] = 2
  [2] = 3
  [3] = 4
  [4] = 5
}

 26> a[2...3] = [10, 20]
 27> a
$R11: [Int] = 5 values {
  [0] = 1
  [1] = 2
  [2] = 10
  [3] = 20
  [4] = 5
}

  • C# 苦しい
csharp> var a = Enumerable.Range(1,5).ToList<int>();
csharp> a.GetType();
System.Collections.Generic.List`1[System.Int32]
csharp> a.InsertRange(2, new List<int>{10,20})       
csharp> a.RemoveRange(4, 2);                         
csharp> a
{ 1, 2, 10, 20, 5 }
 29> a.insert(100, atIndex:0)
 30> a
$R13: [Int] = 6 values {
  [0] = 100
  [1] = 1
  [2] = 2
  [3] = 10
  [4] = 20
  [5] = 5
}
 31> a.removeAtIndex(1)
$R14: (Int) = 1
 32> a
$R15: [Int] = 5 values {
  [0] = 100
  [1] = 2
  [2] = 10
  [3] = 20
  [4] = 5
}
 33> a.removeLast()
$R16: Int = 5
csharp> a.RemoveAt(a.Count() -1)  
csharp> a
{ 1, 2, 10, 20 }
csharp> a.Insert(0, 9999)   
csharp> a
{ 9999, 1, 2, 10, 20 }

Iterating Over an Array

 34> var a = Array(1...5)
a: [Int] = 5 values {
  [0] = 1
  [1] = 2
  [2] = 3
  [3] = 4
  [4] = 5
}
 36> for i in a { print("\(i),")};println()
1,2,3,4,5,

csharp> foreach(var i in Enumerable.Range(1, 5).ToList<int>()){ Console.Write(string.Format("{0},", i));} ; Console.WriteLine();
1,2,3,4,5,
 37> for (i, value) in enumerate(a) { print("\(i):\(value),")};println() 
0:1,1:2,2:3,3:4,4:5,
csharp> foreach(var item in a.OfType<object>().Select((value, index) => new {value, index})){
      >    Console.Write(string.Format("{0}:{1}, ", item.value, item.index));                 
      > }
1:0, 2:1, 3:2, 4:3, 5:4,

Creating and Initializing an Array

 40> var a = [Double](count: 3, repeatedValue: 0.1)
a: [(Double)] = 3 values {
  [0] = 0.10000000000000001
  [1] = 0.10000000000000001
  [2] = 0.10000000000000001
}
csharp> Enumerable.Repeat(0.1, 3).ToList<double>();
{ 0.1, 0.1, 0.1 }

Dictionaries

Dictionary Type Shorthand Syntax / Dictionary Literals

 41> ["TYO": "Tokyo", "DUB": "Dublin"]
$R18: [String : String] = {
  [0] = {
    key = "TYO"
    value = "Tokyo"
  }
  [1] = {
    key = "DUB"
    value = "Dublin"
  }
}

 42> var city : Dictionary<String, String> = ["TYO": "Tokyo", "DUB": "Dublin"] 
city: [String : String] = {
  [0] = {
    key = "TYO"
    value = "Tokyo"
  }
  [1] = {
    key = "DUB"
    value = "Dublin"
  }
}

  • C#: コンストラクタ必要

Accessing and Modifying a Dictionary

 43> city.isEmpty
$R19: Bool = false

 44> city.count
$R20: Int = 2
csharp> var city = new Dictionary<string,string>{{"TYO", "Tokyo"}, {"DUB", "Dublin"}};

csharp> city.Count()
2
 45> city["SFO"] = "San Francisco"

 46> city
$R21: [String : String] = {
  [0] = {
    key = "SFO"
    value = "San Francisco"
  }
  [1] = {
    key = "TYO"
    value = "Tokyo"
  }
  [2] = {
    key = "DUB"
    value = "Dublin"
  }
}
csharp> city["SFO"] = "San Francisco"
csharp> city
{{ "TYO", "Tokyo" }, { "DUB", "Dublin" }, { "SFO", "San Francisco" }}
47> city.removeValueForKey("DUB")
$R22: String? = "Dublin"

 48> city
$R23: [String : String] = {
  [0] = {
    key = "TYO"
    value = "Tokyo"
  }
  [1] = {
    key = "SFO"
    value = "San Francisco"
  }
}
csharp> city.Remove("DUB")
true

csharp> city
{{ "TYO", "Tokyo" }, { "SFO", "San Francisco" }}

Iterating Over a Dictionary

 49> for(key, value) in city { println("\(key)=\(value)") } 
TYO=Tokyo
SFO=San Francisco
csharp> foreach(var item in city){ Console.WriteLine(string.Format("{0}={1} ", item.Key, item.Value));}
TYO=Tokyo 
SFO=San Francisco 
 50> city.keys
$R24: LazyBidirectionalCollection<MapCollectionView<[String : String], String>> = {
  _base = {
    _base = {
      [0] = {
        key = "TYO"
        value = "Tokyo"
      }
      [1] = {
        key = "SFO"
        value = "San Francisco"
      }
    }
    _transform =
  }
}
 51> city.values
$R25: LazyBidirectionalCollection<MapCollectionView<[String : String], String>> = {
  _base = {
    _base = {
      [0] = {
        key = "TYO"
        value = "Tokyo"
      }
      [1] = {
        key = "SFO"
        value = "San Francisco"
      }
    }
    _transform =
  }
}
 52> Array(city.keys)
$R26: [String] = 2 values {
  [0] = "TYO"
  [1] = "SFO"
}
 53> Array(city.values)
$R27: [String] = 2 values {
  [0] = "Tokyo"
  [1] = "San Francisco"
}

 55> [String](city.keys)
$R28: [(String)] = 2 values {
  [0] = "TYO"
  [1] = "SFO"
}

 54> for i in city.keys { println("\(i)")}
TYO
SFO
csharp> city.Keys
{ "TYO", "SFO" }

csharp> city.Values
{ "Tokyo", "San Francisco" }

csharp> city.Keys.GetType()
System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.String]

 Creating an Empty Dictionary

 56> [Int: String]()
$R29: [Int : String] = {}
 57> var d = [String: String]()
d: [String : String] = {}
 58> d["TYO"] = "Tokyo"
 59> d = [:]
 60> d
$R30: [String : String] = {}
csharp> var d = new Dictionary<string, string>();
csharp> d["TYO"] = "Tokyo"
csharp> d
{{ "TYO", "Tokyo" }}

csharp> d.Clear()

csharp> d
{}

Hash Values for Dictionary Key Types

  • Swift : Key はハッシュできないといけない(hashable)
 61> "TYO".hashValue
$R31: Int = 4799450059715620566
  • C# : カスタムオブジェクトをキーにするならGetHashCode, Equalsをオーバーライドすること
csharp> "TYO".GetHashCode()
83562
  • 以下は問題ない
        public class Profile {
            public string Name { get; set; }
        }

        [Test()]
        public void PlayGround()
        {
            var d = new Dictionary<Profile, string> ();

            var p1 = new Profile{ Name = "hoge" };
            var p2 = new Profile{ Name = "foo" };
            d [p1] = "hoge";
            d [p2] = "foo";

            Assert.AreNotEqual (
                p1.GetHashCode (), p2.GetHashCode ());

        }
hidelafoglia
コンピュータプログラミング勉強中です。
https://github.com/hdknr/note
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away