Tag Archives: nested

Cinchoo – Collections, NestedList, Part 7

GetContainedList

ChoNestedList<T> provides a helper method to find the list containing an item.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList topList = new ChoNestedList();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList nestedList1 = new ChoNestedList();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    foreach (string name in topList.GetContainedList("NestedList1-Raj"))
        Console.WriteLine(name);
}

When you run the above code, the output will be

NestedList1-Raj
NestedList1-Peter
NestedList1-Samuel
Press any key to continue . . .

Cinchoo – Collections, NestedList, Part 6

EnumerateAllChildLists

ChoNestedList<T> provides a helper method to get all child list items.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList<int> topList = new ChoNestedList<int>();
    topList.Add(1);
    topList.Add(2);

    ChoNestedList<int> nestedList1 = new ChoNestedList<int>();
    nestedList1.Add(3);
    nestedList1.Add(new List<int>() { 4, 5 });
    nestedList1.Add(6);
    nestedList1.Add(7);
    topList.Add(nestedList1);

    topList.Add(8);

    int count = 0;
    foreach (IList<int> list in topList.EnumerateAllChildLists())
    {
        Console.WriteLine("List {0} contains".FormatString(count++));
        foreach (int x in list)
            Console.WriteLine(x);
    }
}

When you run the above code, the output will be

List 0 contains
3
4
5
6
7
List 1 contains
4
5
Press any key to continue . . .

Cinchoo – Collections, NestedList, Part 5

GetListItemAt

ChoNestedList<T> provides one another helper method to get the underlying list object at a specified index

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList<int> topList = new ChoNestedList<int>();
    topList.Add(1);
    topList.Add(2);

    ChoNestedList<int> nestedList1 = new ChoNestedList<int>();
    nestedList1.Add(3);
    nestedList1.Add(4);
    nestedList1.Add(5);
    topList.Add(nestedList1);

    topList.Add(6);

    Console.WriteLine("Underlying list object at index 3 is");
    foreach (int x in topList.GetListItemAt(3))
        Console.WriteLine(x);

    Console.WriteLine("Underlying list object at index 5 is");
    foreach (int x in topList.GetListItemAt(5))
        Console.WriteLine(x);
}

When you run the above code, the output will be

Underlying list object at index 3 contains
3
4
5
Underlying list object at index 5 contains
1
2
3
4
5
6
Press any key to continue . . .

Cinchoo – Collections, NestedList, Part 4

Clone

ChoNestedList<T> provides deep cloning through ICloneable interface.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList<string> topList = new ChoNestedList<string>();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList<string> nestedList1 = new ChoNestedList<string>();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    ChoNestedList<string> clonedTopList = topList.Clone<ChoNestedList<string>>();

    for (int index = 0; index < clonedTopList.Count; index++)
        Console.WriteLine(clonedTopList[index]);
}

When you run the above code, the output will be

TopList-Tom
TopList-Mark
NestedList1-Raj
NestedList1-Peter
NestedList1-Samuel
TopList-Nancy
Press any key to continue . . .

Cinchoo – Collections, NestedList, Part 3

BinarySerialization

Now you can serialize/deserialize a ChoNestedList<T> object in binary format. Here is how

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList topList = new ChoNestedList();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList nestedList1 = new ChoNestedList();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    ChoNestedList clonedTopList = null;
    using (MemoryStream buffer = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();

        formatter.Serialize(buffer, topList);
        buffer.Seek(0, SeekOrigin.Begin);
        clonedTopList = (ChoNestedList)formatter.Deserialize(buffer);
    }

    for (int index = 0; index < clonedTopList.Count; index++)
        Console.WriteLine(clonedTopList[index]);
}

When you run the above code, the output will be

TopList-Tom
TopList-Mark
NestedList1-Raj
NestedList1-Peter
NestedList1-Samuel
TopList-Nancy
Press any key to continue . . .

Cinchoo – Collections, NestedList, Part 2

XmlSerialization

Now you can serialize/deserialize the ChoNestedList<T> to/from xml. Here is how

Serialize

Here you can see how to serialize ChoNestedList<T> object to xml string.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList<string> topList = new ChoNestedList<string>();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList<string> nestedList1 = new ChoNestedList<string>();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    Console.WriteLine(topList.ToXml());
}

When you run the above code, the output will be

<ChoNestedList>
  <ChoTuple>
    <First><string>TopList-Tom</string></First>
    <Second />
  </ChoTuple>
  <ChoTuple>
    <First><string>TopList-Mark</string></First>
    <Second />
  </ChoTuple>
  <ChoTuple>
    <First />
    <Second><ChoNestedList>
  <ChoTuple>
    <First><string>NestedList1-Raj</string></First>
    <Second />
  </ChoTuple>
  <ChoTuple>
    <First><string>NestedList1-Peter</string></First>
    <Second />
  </ChoTuple>
  <ChoTuple>
    <First><string>NestedList1-Samuel</string></First>
    <Second />
  </ChoTuple>
</ChoNestedList></Second>
  </ChoTuple>
  <ChoTuple>
    <First><string>TopList-Nancy</string></First>
    <Second />
  </ChoTuple>
</ChoNestedList>
Press any key to continue . . .

Deserialize

In here, you can see how to deserialize a xml string to ChoNestedList<T> object.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic

Sample code,

static void Main(string[] args)
{
    ChoNestedList<string> topList = new ChoNestedList<string>();
    topList.Add("TopList-Tom");
    topList.Add("TopList-Mark");

    ChoNestedList<string> nestedList1 = new ChoNestedList<string>();
    nestedList1.Add("NestedList1-Raj");
    nestedList1.Add("NestedList1-Peter");
    nestedList1.Add("NestedList1-Samuel");
    topList.Add(nestedList1);

    topList.Add("TopList-Nancy");

    string xml = topList.ToXml();
    ChoNestedList<string> deserializedList = xml.ToObjectFromXml<ChoNestedList<string>>();

    for (int index = 0; index < deserializedList.Count; index++)
        Console.WriteLine(deserializedList[index]);
}

When you run the above code, the output will be

TopList-Tom
TopList-Mark
NestedList1-Raj
NestedList1-Peter
NestedList1-Samuel
TopList-Nancy
Press any key to continue . . .

Cinchoo – Nested Xml files

ChoXmlDocument

.NET provides standard XmlDocument object that represents a XML document. But lacks to support multiple sub documents inside a Xml document. Cinchoo addresses this feature through ChoXmlDocument class, where you can specify multiple nested Xml files. It provides an opportunities to break a large Xml document into small manageable sub-documents.

For a sample Xml document as below

<?xml version="1.0" encoding="utf-8" ?>
<employees>
 <employee name="Top-Tom" state="NY" />
 <employee name="Include1-Mark" state="NM" />
 <employee name="Include11-Tom" state="MD" />
 <employee name="Include1-Tom" state="AZ" />
 <employee name="Top-Mark" state="NJ" />
</employees>

I’m going to break them down to 3 xml files as below (just for illustrative purpose)

1. XmlTop.xml

<?xml version="1.0" encoding="utf-8" ?>
<employees xmlns:cinchoo="http://schemas.cinchoo.com/cinchoo/01/framework">
 <employee name="Top-Tom" state="NY" />
 <cinchoo:include path="XmlIncludeFile1.xml" />
 <employee name="Top-Mark" state="NJ" />
</employees>

2. XmlIncludeFile1.xml

<?xml version="1.0" encoding="utf-8" ?>
<employee name="Include1-Mark" state="NM" />
<cinchoo:include xmlns:cinchoo="http://schemas.cinchoo.com/cinchoo/01/framework" path="XmlIncludeFile11.xml" />
<employee name="Include1-Tom" state="AZ" />

3. XmlIncludeFile11.xml

<?xml version="1.0" encoding="utf-8" ?>
<employee name="Include11-Tom" state="MD" />

How to load and use the document

1. Add reference to Cinchoo.Core.dll

2. Namespace: Cinchoo.Core.Xml

using (ChoXmlDocument xmlDocument = new ChoXmlDocument("C:\XmlTop.xml"))
{
    Console.WriteLine(ChoXmlDocument.IndentXMLString(xmlDocument.XmlDocument.OuterXml));
}

Output of the above code would be

<?xml version="1.0" encoding="utf-8"?>
<employees xmlns:cinchoo="http://schemas.cinchoo.com/cinchoo/01/framework">
 <employee name="Top-Tom" state="NY" />
 <!--DO NOT REMOVE - BEGIN INCLUDE C:\XmlIncludeFile1.xml-->
 <employee name="Include1-Mark" state="NM" />
 <!--DO NOT REMOVE - BEGIN INCLUDE C:\XmlIncludeFile11.xml-->
 <employee name="Include11-Tom" state="MD" />
 <!--DO NOT REMOVE - END INCLUDE C:\XmlIncludeFile11.xml-->
 <employee name="Include1-Tom" state="AZ" />
 <!--DO NOT REMOVE - END INCLUDE C:\XmlIncludeFile1.xml-->
 <employee name="Top-Mark" state="NJ" />
</employees>

Or you can use the XmlDocument object exposed as member from ChoXmlDocument object to do other operation on the document.

Cinchoo – ChoSynchronizedEnumerator

ChoSynchronizedEnumerator

This is one another custom enumerator that Cinchoo framework provides. ChoSynchronizedEnumerator is a custom enumerator iterates over collection items synchronized way in multi-threaded applications.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic or Cinchoo.Core.Collections

Using it on Generic Collections

Use Cinchoo.Core.Collection.Generic namespace.

Sample 1: Here we will see how to use it on List<> object,

Below sample iterates over List<> object by two threads simultaneously.

static void Main(string[] args)
{
    object syncRoot = new object();
    List<string> symbols = new List<string>();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    ManualResetEvent evt = new ManualResetEvent(false);
    for (int z = 0; z < 2; z++)
    {
        ThreadPool.QueueUserWorkItem((state) =>
            {
                Thread.CurrentThread.Name = String.Format("Thread_{0}", state);
                evt.WaitOne();
                int counter = 0;
                foreach (string symbol in new ChoSynchronizedEnumerator<string>(symbols, syncRoot))
                {
                    Console.WriteLine("{0}. {1} -- {2}", ++counter, symbol, Thread.CurrentThread.Name);
                }
            }, z);
    }

    evt.Set();
    Console.WriteLine("Press any key to continue...");
    Console.ReadLine();
}

When you run the above code, you will see the output consistently all the time as below. In a non-synchronous model, the output will product unpredictable sequence of results.

1. ITEM0 -- Thread_0
2. ITEM1 -- Thread_0
3. ITEM2 -- Thread_0
4. ITEM3 -- Thread_0
5. ITEM4 -- Thread_0
1. ITEM0 -- Thread_1
2. ITEM1 -- Thread_1
3. ITEM2 -- Thread_1
4. ITEM3 -- Thread_1
5. ITEM4 -- Thread_1
Press any key to continue . . .

Sample 2: Here we will see how to use it on Dictionary<> object

Below sample iterates over Dictionary<> object by two threads simultaneously.

static void Main(string[] args)
{
    object syncRoot = new object();
    Dictionary<int, string> dict = new Dictionary<int, string>();

    for (int x = 0; x < 5; x++)
        dict.Add(x, String.Format("VALUE{0}", x));

    ManualResetEvent evt = new ManualResetEvent(false);
    for (int z = 0; z < 2; z++)
    {
        ThreadPool.QueueUserWorkItem((state) =>
            {
                Thread.CurrentThread.Name = String.Format("Thread_{0}", state);
                evt.WaitOne();
                int counter = 0;
                foreach (KeyValuePair<int, string> keyValue in new ChoSynchronizedEnumerator<KeyValuePair<int, string>>(dict, syncRoot))
                {
                    Console.WriteLine("{0}. {1} -- {2}", keyValue.Key, keyValue.Value, Thread.CurrentThread.Name);
                }
            }, z);
    }

    evt.Set();
    Console.WriteLine("Press any key to continue...");
    Console.ReadLine();
}

When you run the above code, you will see the output consistently all the time as below. In a non-synchronous model, the output will product unpredictable sequence of results.

0. VALUE0 -- Thread_0
1. VALUE1 -- Thread_0
2. VALUE2 -- Thread_0
3. VALUE3 -- Thread_0
4. VALUE4 -- Thread_0
0. VALUE0 -- Thread_1
1. VALUE1 -- Thread_1
2. VALUE2 -- Thread_1
3. VALUE3 -- Thread_1
4. VALUE4 -- Thread_1
Press any key to continue . . .

Using it on Non Generic Collections

Use Cinchoo.Core.Collection namespace.

Sample 3: Here we will see how to use it on ArrayList object

Below sample iterates over ArrayList object by two threads simultaneously.

static void Main(string[] args)
{
    object syncRoot = new object();
    ArrayList symbols = new ArrayList();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ZITEM{0}", x));

    ManualResetEvent evt = new ManualResetEvent(false);
    for (int z = 0; z < 2; z++)
    {
        ThreadPool.QueueUserWorkItem((state) =>
            {
                Thread.CurrentThread.Name = String.Format("Thread_{0}", state);
                evt.WaitOne();
                int counter = 0;
                foreach (string symbol in new ChoSynchronizedEnumerator(symbols, syncRoot))
                {
                    Console.WriteLine("{0}. {1} -- {2}", ++counter, symbol, Thread.CurrentThread.Name);
                }
            }, z);
    }

    evt.Set();
    Console.WriteLine("Press any key to continue...");
    Console.ReadLine();
}

When you run the above code, you will see the output consistently all the time as below. In a non-synchronous model, the output will product unpredictable sequence of results.

1. ZITEM0 -- Thread_0
2. ZITEM1 -- Thread_0
3. ZITEM2 -- Thread_0
4. ZITEM3 -- Thread_0
5. ZITEM4 -- Thread_0
1. ZITEM0 -- Thread_1
2. ZITEM1 -- Thread_1
3. ZITEM2 -- Thread_1
4. ZITEM3 -- Thread_1
5. ZITEM4 -- Thread_1
Press any key to continue . . .

Sample 4: Here we will see how to use it on Hashtable object,

Below sample iterates over Hashtable object by two threads simultaneously.

static void Main(string[] args)
{
    object syncRoot = new object();
    Hashtable dict = new Hashtable();

    for (int x = 0; x < 5; x++)
        dict.Add(x, String.Format("VALUE{0}", x));

    ManualResetEvent evt = new ManualResetEvent(false);
    for (int z = 0; z < 2; z++)
    {
        ThreadPool.QueueUserWorkItem((state) =>
            {
                Thread.CurrentThread.Name = String.Format("Thread_{0}", state);
                evt.WaitOne();
                foreach (DictionaryEntry dictEntry in new ChoSynchronizedEnumerator(dict, syncRoot))
                {
                    Console.WriteLine("{0}. {1} -- {2}", dictEntry.Key, dictEntry.Value, Thread.CurrentThread.Name);
                }
            }, z);
    }

    evt.Set();
    Console.WriteLine("Press any key to continue...");
    Console.ReadLine();
}

When you run the above code, you will see the output consistently all the time as below. In a non-synchronous model, the output will product unpredictable sequence of results.

4. VALUE4 -- Thread_0
3. VALUE3 -- Thread_0
2. VALUE2 -- Thread_0
1. VALUE1 -- Thread_0
0. VALUE0 -- Thread_0
4. VALUE4 -- Thread_1
3. VALUE3 -- Thread_1
2. VALUE2 -- Thread_1
1. VALUE1 -- Thread_1
0. VALUE0 -- Thread_1
Press any key to continue . . .

PS: Please be careful about using this enumerator, you must dispose the enumerator to order to avoid contention, deadlock issues.

Cinchoo – ChoConstraintEnumerator

ChoConstraintEnumerator

This is one another custom enumerator that Cinchoo framework provides. ChoConstraintEnumerator is a custom enumerator iterates over collection items matches the passed constraint logic.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic or Cinchoo.Core.Collections

Using it on Generic Collections

Use Cinchoo.Core.Collection.Generic namespace.

Sample 1: Here we will see how to use it on List<> object, matches items having value 3 or 5

static void Main(string[] args)
{
    List<string> symbols = new List<string>();

    for (int x = 0; x < 7; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    int counter = 0;
    foreach (string symbol in new ChoConstraintEnumerator<string>(symbols, (x) => x.EndsWith("3") || x.EndsWith("5")))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ITEM3
2. ITEM5
Press any key to continue . . .

Sample 2: Here we will see how to use it on Dictionary<> object, matches items having key either 3 or 5

static void Main(string[] args)
{
    Dictionary<int, string> dict = new Dictionary<int, string>();

    for (int x = 0; x < 7; x++)
        dict.Add(x, String.Format("VALUE{0}", x));

    foreach (KeyValuePair<int, string> keyValue in new ChoConstraintEnumerator<KeyValuePair<int, string>>(dict, (x) => x.Key == 3 || x.Key == 5))
    {
        Console.WriteLine("{0}. {1}", keyValue.Key, keyValue.Value);
    }
}

When you run the above code, the output will be

3. VALUE3
5. VALUE5
Press any key to continue . . .

Using it on Non Generic Collections

Use Cinchoo.Core.Collection namespace.

Sample 3: Here we will see how to use it on ArrayList object, matches items having value 3 or 5

static void Main(string[] args)
{
    ArrayList symbols1 = new ArrayList();

    for (int x = 0; x < 7; x++)
        symbols1.Add(String.Format("ZITEM{0}", x));

    int counter1 = 0;
    foreach (object symbol in new ChoConstraintEnumerator(symbols1, (x) => x.ToString().EndsWith("3") || x.ToString().EndsWith("5")))
    {
        Console.WriteLine("{0}. {1}", ++counter1, symbol);
    }
}

When you run the above code, the output will be

1. ZITEM3
2. ZITEM5
Press any key to continue . . .

Sample 4: Here we will see how to use it on Hashtable object, matches items having key either 3 or 5

static void Main(string[] args)
{
    Hashtable hash = new Hashtable();

    for (int x = 0; x < 7; x++)
        hash.Add(x, String.Format("VALUE{0}", x));

    foreach (DictionaryEntry dictEntry in new ChoConstraintEnumerator(hash, (x) => ((DictionaryEntry)x).Key.ToString() == "3" || ((DictionaryEntry)x).Key.ToString() == "5"))
    {
        Console.WriteLine("{0}. {1}", dictEntry.Key, dictEntry.Value);
    }
}

When you run the above code, the output will be

5. VALUE5
3. VALUE3
Press any key to continue . . .

Cinchoo – ChoReverseEnumerator

ChoReverseEnumerator

This is one another custom enumerator that Cinchoo framework provides. ChoReverseEnumerator is a custom enumerator iterates over collection items in reverse order.

How to use

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Collections.Generic or Cinchoo.Core.Collections

Using it on Generic Collections

Use Cinchoo.Core.Collection.Generic namespace.

Sample 1: Here we will see how to use it on List<> object

static void Main(string[] args)
{
    List<string> symbols = new List<string>();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ITEM{0}", x));

    int counter = 0;
    foreach (string symbol in new ChoReverseEnumerator<string>(symbols))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ITEM4
2. ITEM3
3. ITEM2
4. ITEM1
5. ITEM0
Press any key to continue . . .

Sample 2: Here we will see how to use it on Dictionary<> object

static void Main(string[] args)
{
    Dictionary<int, string> symbols = new Dictionary<int, string>();

    for (int x = 0; x < 5; x++)
        symbols.Add(x, String.Format("VALUE{0}", x));

    foreach (KeyValuePair<int, string> keyValue in new ChoReverseEnumerator<KeyValuePair<int, string>>(symbols))
    {
        Console.WriteLine("{0}. {1}", keyValue.Key, keyValue.Value);
    }
}

When you run the above code, the output will be

4. VALUE4
3. VALUE3
2. VALUE2
1. VALUE1
0. VALUE0
Press any key to continue . . .

Using it on Non Generic Collections

Use Cinchoo.Core.Collection namespace.

Sample 3: Here we will see how to use it on ArrayList object, with 2 steps

static void Main(string[] args)
{
    ArrayList symbols = new ArrayList();

    for (int x = 0; x < 5; x++)
        symbols.Add(String.Format("ZITEM{0}", x));

    int counter = 0;
    foreach (object symbol in new ChoReverseEnumerator(symbols))
    {
        Console.WriteLine("{0}. {1}", ++counter, symbol);
    }
}

When you run the above code, the output will be

1. ZITEM4
2. ZITEM3
3. ZITEM2
4. ZITEM1
5. ZITEM0
Press any key to continue . . .

Sample 4: Here we will see how to use it on Hashtable object, with 2 steps

static void Main(string[] args)
{
    Hashtable hash = new Hashtable();

    for (int x = 0; x < 5; x++)
        hash.Add(x, String.Format("VALUE{0}", x));

    foreach (DictionaryEntry dictEntry in new ChoReverseEnumerator(hash))
    {
        Console.WriteLine("{0}. {1}", dictEntry.Key, dictEntry.Value);
    }
}

When you run the above code, the output will be

0. VALUE0
1. VALUE1
2. VALUE2
3. VALUE3
4. VALUE4
Press any key to continue . . .