JSON and C#

To work with Json using C#, it is need to use Newtonsoft (.net library). This library provides methods that allows the programmer serialize and deserialize objects and more.

Serialization: Process of converting a object into a stream of bytes that can be sent through applications. The following code can be serialized and converted into the previous json.

Deserialization: Process of converting a json/stream of bytes into an object. Its exactly the opposite process of serialization. The previous json can be deserialized into an C# object as demonstrated in examples below.

using Newtonsoft.Json;
class Author
{
[JsonProperty("id")] // Set the variable below to represent the json attribute
public int id; //"id"
[JsonProperty("name")]
public string name;
[JsonProperty("type")]
public string type;
[JsonProperty("books")]
public Book[] books;
public Author(int id, string name, string type, Book[] books) {
this.id = id;
this.name = name;
this.type= type;
this.books = books;
}
}
class Book
{
[JsonProperty("name")]
public string name;
[JsonProperty("date")]
public DateTime date;
}

Serialization

static void Main(string[] args)
{
Book[] books = new Book[3];
Author author = new Author(89,"Aldous Huxley","Author",books);
string objectDeserialized = JsonConvert.SerializeObject(author);
//Converting author into json
}

Deserialization

You can receive a json from anywhere, a file or even a server so it is not included in the following code.
static void Main(string[] args)
{
string jsonExample; // Has the previous json
Author author = JsonConvert.DeserializeObject<Author>(jsonExample);
}
The method “.DeserializeObject” deserializes ‘jsonExample’ into an “Author” object. This is why it is important to set the json variables in the classes definition, so the method access it in order to fill it.

LINQ Queries

Many LINQ functions both operate on an IEnumerable<TSource> and also return an IEnumerable<TResult>. The type parameters TSource and TResult may or may not refer to the same type, depending on the method in question and any functions passed to it.

First()

// Returns "a":
new[] { "a", "b" }.First();
// Returns "b":
new[] { "a", "b" }.First(x => x.Equals("b"));
// Returns "ba":
new[] { "ba", "be" }.First(x => x.Contains("b"));
// Throws InvalidOperationException:
new[] { "ca", "ce" }.First(x => x.Contains("b"));

FirstOrDefault()

Returns the first element of a sequence, or the first element matching the provided predicate.
If the sequence contains no elements, or no elements matching the provided predicate, returns the default value of the sequence type using default(T).

// Returns "a":
new[] { "a", "b" }.FirstOrDefault();

// Returns "b":
new[] { "a", "b" }.FirstOrDefault(x => x.Equals("b"));

Last()

// Returns "b":
new[] { "a", "b" }.Last();
// Returns "a":
new[] { "a", "b" }.Last(x => x.Equals("a"));
// Returns "be":
new[] { "ba", "be" }.Last(x => x.Contains("b"));

LastOrDefault()

// Returns "b":
new[] { "a", "b" }.LastOrDefault();
// Returns "a":
new[] { "a", "b" }.LastOrDefault(x => x.Equals("a"));

Single()

If the sequence contains exactly one element, or exactly one element matching the provided predicate, that element is returned.

// Throws InvalidOperationException because sequence contains more than one element:
new[] { "a", "b" }.Single();
// Returns "b":
new[] { "a", "b" }.Single(x => x.Equals("b"));
// Throws InvalidOperationException:
new[] { "a", "b" }.Single(x => x.Equals("c"));
// Throws InvalidOperationException:
new string[0].Single();
// Throws InvalidOperationException because sequence contains more than one element:
new[] { "a", "a" }.Single();

SingleOrDefault()

If the sequence contains exactly one element, or exactly one element matching the provided predicate, that element is returned.
If the sequence contains no elements, or no elements matching the provided predicate, default(T) is returned.

// returns "a"
new[] { "a", "b" }.SingleOrDefault(x => x == "a");
// Returns null:
new[] { "a", "b" }.SingleOrDefault(x => x == "c");
// Throws InvalidOperationException:
new[] { "a", "a" }.SingleOrDefault(x => x == "a");
// Throws InvalidOperationException:
new[] { "a", "b" }.SingleOrDefault();

Except

The Except method returns the set of items which are contained in the first collection but are not contained in the second.

int[] first = { 1, 2, 3, 4 };
int[] second = { 0, 2, 3, 5 };
IEnumerable<int> inFirstButNotInSecond = first.Except(second);
// inFirstButNotInSecond = { 1, 4 }

Note that Except implies Distinct (i.e., it removes repeated elements). For example:
int[] third = { 1, 1, 1, 2, 3, 4 };
IEnumerable<int> inThirdButNotInSecond = third.Except(second);
// inThirdButNotInSecond = { 1, 4 }

SelectMany

The SelectMany linq method ‘flattens’ an IEnumerable<IEnumerable<T>> into an IEnumerable<T>.

All of the T elements within the IEnumerable instances contained in the source IEnumerable will be combined into a single IEnumerable.

var words = new [] { "a,b,c", "d,e", "f" };
var splitAndCombine = words.SelectMany(x => x.Split(','));
// returns { "a", "b", "c", "d", "e", "f" }

More real-world example
class School
{
public Student[] Students { get; set; }
}
class Student
{
public string Name { get; set; }
}
var schools = new [] {
new School(){ Students = new [] { new Student { Name="Bob"}, new Student { Name="Jack"} }},
new School(){ Students = new [] { new Student { Name="Jim"}, new Student { Name="John"} }}
};

var allStudents = schools.SelectMany(s=> s.Students);

foreach(var student in allStudents)
{
Console.WriteLine(student.Name);
}

Any

Any is used to check if any element of a collection matches a condition or not.

1. Empty parameter
Any: Returns true if the collection has any elements and false if the collection is empty:
var numbers = new List<int>();
bool result = numbers.Any(); // false
var numbers = new List<int>(){ 1, 2, 3, 4, 5};
bool result = numbers.Any(); //true
2. Lambda expression as parameter
Any: Returns true if the collection has one or more elements that meet the condition in the lambda expression:
var arrayOfStrings = new string[] { "a", "b", "c" };
arrayOfStrings.Any(item => item == "a"); // true
arrayOfStrings.Any(item => item == "d"); // false
3. Empty collection
Any: Returns false if the collection is empty and a lambda expression is supplied:
var numbers = new List<int>();
bool result = numbers.Any(i => i >= 0); // false

Skip and Take

The Skip method returns a collection excluding a number of items from the beginning of the source collection.

The number of items excluded is the number given as an argument. If there are less items in the collection than specified in the argument then an empty collection is returned.

The Take method returns a collection containing a number of elements from the beginning of the source collection.

var values = new [] { 5, 4, 3, 2, 1 };
var skipTwo = values.Skip(2); // { 3, 2, 1 }
var takeThree = values.Take(3); // { 5, 4, 3 }
var skipOneTakeTwo = values.Skip(1).Take(2); // { 4, 3 }
var takeZero = values.Take(0); // An IEnumerable<int> with 0 items

Zip

The Zip extension method acts upon two collections. It pairs each element in the two series together based on position.

int[] numbers = { 3, 5, 7 };
string[] words = { "three", "five", "seven", "ignored" };
IEnumerable<string> zip = numbers.Zip(words, (n, w) => n + "=" + w);
Output:
3=three
5=five
7=seven

Range and Repeat

// Generate a collection containing the numbers 1-100 ([1, 2, 3, ..., 98, 99, 100])
var range = Enumerable.Range(1,100);

// Generate a collection containing "a", three times (["a","a","a"])
var repeatedValues = Enumerable.Repeat("a", 3);

All

All is used to check, if all elements of a collection match a condition or not.

Returns true if the collection is empty and a lambda expression is supplied.

var numbers = new List<int>(){ 1, 2, 3, 4, 5};
bool result = numbers.All(i => i < 10); // true
bool result = numbers.All(i => i >= 3); // false

Aggregate

Aggregate Applies an accumulator function over a sequence.

int[] intList = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = intList.Aggregate((prevSum, current) => prevSum + current);
// sum = 55

string[] stringList = { "Hello", "World", "!" };
string joinedString = stringList.Aggregate((prev, current) => prev + " " + current);
// joinedString = "Hello World !"

Distinct

int[] array = { 1, 2, 3, 4, 2, 5, 3, 1, 2 };
var distinct = array.Distinct();
// distinct = { 1, 2, 3, 4, 5 }

Where

Returns a subset of items which the specified predicate is true for them.
List<string> trees = new List<string>{ "Oak", "Birch", "Beech", "Elm", "Hazel", "Maple" };

// Select all trees with name of length 3
var shortTrees = trees.Where(tree => tree.Length == 3); // Oak, Elm

Contains

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var result1 = numbers.Contains(4); // true
var result2 = numbers.Contains(8); // false

Sum

int[] numbers = new int[] { 1, 4, 6 };
Console.WriteLine( numbers.Sum() ); //outputs 11

OrderBy

int[] numbers = {2, 1, 0, -1, -2};
IEnumerable<int> ascending = numbers.OrderBy(x => x);
// returns {-2, -1, 0, 1, 2}

ToDictionary

IEnumerable<User> users = GetUsers();
Dictionary<int, User> usersById = users.ToDictionary(x => x.Id);

is the same as:

Dictionary<int, User> usersById = new Dictionary<int User>();
foreach (User u in users)
{
usersById.Add(u.Id, u);
}

You can also pass a second parameter to the ToDictionary method, which is of type Func<TSource,?TElement>
and returns the Value to be added for each entry.
IEnumerable<User> users = GetUsers();
Dictionary<int, string> userNamesById = users.ToDictionary(x => x.Id, x => x.Name);

Concat

List<int> foo = new List<int> { 1, 2, 3 };
List<int> bar = new List<int> { 3, 4, 5 };
// Through Enumerable static class
var result = Enumerable.Concat(foo, bar).ToList(); // 1,2,3,3,4,5

Select – Transforming elements

Select allows you to apply a transformation to every element in any data structure implementing IEnumerable.

List<String> trees = new List<String>{ "Oak", "Birch", "Beech", "Elm", "Hazel", "Maple" };
//The below select stament transforms each element in tree into its first character.
IEnumerable<String> initials = trees.Select(tree => tree.Substring(0, 1));
foreach (String initial in initials) {
System.Console.WriteLine(initial);
}

Union

int[] numbers1 = { 1, 2, 3 };
int[] numbers2 = { 2, 3, 4, 5 };
var allElement = numbers1.Union(numbers2); // AllElement now contains 1,2,3,4,5

Reverse

Inverts the order of the elements in a sequence.

int[] array = { 1, 2, 3, 4 };
var reverse = array.Reverse();