---
# System prepended metadata

title: Untitled

---

## GroupJoin

- A resultSelector função é chamada apenas uma vez para cada outer elemento junto com uma coleção de todos os inner elementos que correspondem ao outer elemento. 

```csharp=
record Pessoa(string nome);
record Fruta(string nome, Pessoa dono);
    
Pessoa pedro = new Pessoa("Pedro");
Pessoa jorge = new Pessoa("Jorge");
Pessoa danilo = new Pessoa("Danilo");

Fruta abacaxi = new Fruta("Abacaxi", pedro);
Fruta maca = new Fruta("Maça", pedro);
Fruta banana = new Fruta("Banana", pedro);
Fruta morango = new Fruta("Morango", danilo);

List<Pessoa> pessoas = new List<Pessoa>() { pedro, jorge, danilo };
List<Fruta> frutas = new List<Fruta>() { abacaxi, maca, banana, morango };

var query = pessoas
    .GroupJoin(frutas,
        p => p,
        f => f.dono,
        (pessoas, frutaColecao) =>
        new
        {
            NomeDono = pessoas.nome,
            Frutas = frutaColecao.Select(s => s.nome)
        });

foreach (var item in query)
{
    Console.WriteLine($"Dono {item.NomeDono}, Frutas: {string.Join(",", item.Frutas)}");
}
            
// Dono Pedro, Frutas: Abacaxi,Maça     
// Dono Jorge, Frutas:         
// Dono Danilo, Frutas: Morango   

```

## Join

```csharp=
Pessoa pedro = new Pessoa("Pedro");
Pessoa jorge = new Pessoa("Jorge");
Pessoa danilo = new Pessoa("Danilo");

Fruta abacaxi = new Fruta("Abacaxi", pedro);
Fruta maca = new Fruta("Maça", pedro);
Fruta banana = new Fruta("Banana", pedro);
Fruta morango = new Fruta("Morango", danilo);

List<Pessoa> pessoas = new List<Pessoa>() { pedro, jorge, danilo };
List<Fruta> frutas = new List<Fruta>() { abacaxi, maca, banana, morango };

var query = pessoas
    .Join(frutas,
        p => p,
        f => f.dono,
        (pessoas, fruta) =>
        new
        {
            NomeDono = pessoas.nome,
            Fruta = fruta.nome
        });

foreach (var item in query)
{
    Console.WriteLine($"Dono {item.NomeDono}, Frutas: {item.Fruta}");
    // Dono Pedro, Frutas: Abacaxi
    // Dono Pedro, Frutas: Maça 
    // Dono Pedro, Frutas: Banana 
    // Dono Danilo, Frutas: Morango  
}

Console.ReadKey();
```

- Join preserva a ordem dos elementos de outer e para cada um desses elementos, a ordem dos elementos correspondentes de inner.

- Um GroupJoin é em SQL o que chamamos de “Left Outer JOIN”, enquanto um Join em SQL se refere a “Inner Join”. Resumindo, um GroupJoin fará um link entre 2 entidades, mesmo que o lado direito do link não tenha nada para vincular. Em contraste, o Join vinculará 2 entidades apenas se ambas as entidades contiverem um link entre elas.

## OrderBy, OrderByDescending

```csharp=
class Pet
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public static void OrderByEx1()
{
    Pet[] pets = { new Pet { Name="Barley", Age=8 },
                   new Pet { Name="Boots", Age=4 },
                   new Pet { Name="Whiskers", Age=1 } };

    IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);

    foreach (Pet pet in query)
    {
        Console.WriteLine("{0} - {1}", pet.Name, pet.Age);
    }
}

/*
 This code produces the following output:

 Whiskers - 1
 Boots - 4
 Barley - 8
*/
```

## ThenBy, ThenByDescending

```csharp=
string[] fruits = { "grape", "passionfruit", "banana", "mango",
                      "orange", "raspberry", "apple", "blueberry" };

// Sort the strings first by their length and then
//alphabetically by passing the identity selector function.
IEnumerable<string> query =
    fruits.OrderBy(fruit => fruit.Length).ThenBy(fruit => fruit);

foreach (string fruit in query)
{
    Console.WriteLine(fruit);
}

/*
    This code produces the following output:

    apple
    grape
    mango
    banana
    orange
    blueberry
    raspberry
    passionfruit
*/
```

- Esse método é implementado usando a execução adiada. O valor de retorno imediato é um objeto que armazena todas as informações necessárias para executar a ação. A consulta representada por esse método **não é executada até que o objeto seja enumerado chamando o GetEnumerator** método diretamente ou usando o foreach no Visual C# ou For Each no Visual Basic.

## Reverse

- Ao contrário do OrderBy , esse método de classificação não considera os próprios valores reais para determinar a ordem. Em vez disso, ele apenas retorna os elementos na ordem inversa da qual eles são produzidos pela fonte subjacente.

```csharp=
char[] apple = { 'a', 'p', 'p', 'l', 'e' };

char[] reversed = apple.Reverse().ToArray();

foreach (char chr in reversed)
{
    Console.Write(chr + " ");
}
Console.WriteLine();

/*
 This code produces the following output:

 e l p p a
*/
```

> https://docs.microsoft.com/pt-br/dotnet/api/system.linq.enumerable.groupjoin?view=net-5.0
> https://patrickdesjardins.com/blog/linq-groupjoin-and-join-differences

## Select
O operador Select sempre retorna uma coleção IEnumerable que contém elementos baseados em uma função de transformação.

```csharp=
namespace select
{
    public class Produto
    {
        public string Nome;

        public Produto(string nome)
        {
            Nome = nome;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var produtos = new[]
            {
                new Produto("MORANGO"),
                new Produto("LARANJA")
            };

            var resultado = produtos.Select(n => n.Nome.ToLower());

            foreach(var nome in resultado)
            {
                Console.WriteLine(nome);
            }
        }
    }
}
```

## SelectMany

O SelectMany no LINQ é usado para projetar cada elemento de uma sequência para um IEnumerable<T> e, em seguida, achatar as sequências resultantes em uma sequência. Isso significa que o operador SelectMany combina os registros de uma sequência de resultados e, em seguida, converte-o em um resultado.

```csharp=

static void Main(string[] args)
{
    string[] frutas = { "Uva", "laranja", "banana" };
    int[] numeros = { 1, 2, 3 };

    var resultado = frutas.SelectMany(f => numeros, (f, a) => new
    {
        Fruta = f,
        Numero = a
    });

    foreach (var o in resultado)
      Console.WriteLine(o.Fruta + ", " + o.Numero);
}

resultado:

Uva, 1
Uva, 2
Uva, 3
laranja, 1
laranja, 2
laranja, 3
banana, 1
banana, 2
banana, 3
```


### Skip

Ele pula o número especificado de elementos em uma coleção

```csharp=
static void Main(string[] args)
{
    string[] produtos = { "banana", "pera", "uva", "melancia", "maca", "limao" };

    var resultado = produtos.Skip(4);

    foreach (string produto in resultado)
       Console.WriteLine(produto);
}

Resultado:
maca
limao
```

### SkipWhile
Ele retorna uma nova coleção que inclui todos os elementos restantes uma vez que a condição especificada se torna falsa para qualquer elemento.

```csharp=
static void Main(string[] args)
{
     string[] numeros = { "one", "two", "three", "four", "five", "six" };

     var resultado = numeros.SkipWhile(w => w.Length == 3);

     foreach (string numero in resultado)
        Console.WriteLine(numero);
}

Resultado:
Three
Four
Five
Six
```

### Take
O método de extensão Take() retorna o número especificado de elementos a partir do primeiro elemento.

```csharp=
IList<string> lista = new List<string>(){ "One", "Two", "Three", "Four", "Five" };

var novalista = lista.Take(2);

foreach(var str in novalista)
    Console.WriteLine(str);
    
    
Resultado:
One
Two
```


### TakeWhile

O método de extensão TakeWhile() retorna os elementos da coleção dada até que a condição especificada seja verdadeira. Se o primeiro elemento em si não satisfaz a condição, então retorna uma coleção vazia.

```csharp=
IList<string> strList = new List<string>() { "Three", "Four", "Five", "Hundred"  };


var result = strList.TakeWhile(s => s.Length > 4);

foreach(string str in result)
        Console.WriteLine(str);
        
Resultado:
Three
```


## Quantifiers
### All
- Determina se todos os elementos de uma sequência atendem a uma condição.
- Retorna bool

```csharp=
List<int> lista = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
bool pares = lista.All(x => x % 2 == 0);

Console.WriteLine(pares);

// False
```
### Any
- Determina se qualquer elemento de uma sequência existe ou atende a uma condição
- Retorna bool


```csharp=
List<int> lista = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
bool temItens = lista.Any();
bool contemNum = lista.Any(x => x == 5);

Console.WriteLine(temItens);
Console.WriteLine(contemNum);

// True
// contemNum
```

### Contains

- Determina se uma sequência contém um elemento especificado.
- Retorna bool
- System.Linq

```csharp=
List<int> lista = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
bool contem = lista.Contains(3);

Console.WriteLine(contem);

// True
```

## Restriction
### Where

- Filtra uma sequência de valores com base num predicado.
- Retorna IEnumerable<TSource>

```csharp=
List<int> lista = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List<int> filtro = lista.Where(x => x > 5).ToList();

foreach (int item in filtro)
{
    Console.WriteLine(item);
}

// { 6, 7, 8, 9, 10 }
```

## Set
### Distinct
- Retorna os elementos distintos de uma sequência usando o comparador de igualdade padrão para comparar valores.
- Retorna IEnumerable<TSource>

```csharp=
List<int> lista = new List<int> { 1, 2, 3, 3, 5, 7, 4, 5, 6, 7 };
List<int> filtro = lista.Distinct().ToList();

foreach (int item in filtro)
{
    Console.WriteLine(item);
}
// { 1, 2, 3, 5, 7, 4, 6}
```

### Except
- Produz a diferença de conjunto de duas sequências.
- Retorna IEnumerable<TSource>

```csharp=
List<int> lista = new List<int> { 1, 2, 3, 5, 7  };
List<int> lista2 = new List<int> { 1, 2};
List<int> filtro = lista.Except(lista2).ToList();

foreach (int item in filtro)
{
    Console.WriteLine(item);
}

// { 3, 5, 7 }
```

### Intersect
- Produz a interseção de conjunto de duas sequências.
- Retorna IEnumerable<TSource>

```csharp=
List<int> lista = new List<int> { 1, 2, 3, 5, 7  };
List<int> lista2 = new List<int> { 1, 2 };
List<int> filtro = lista.Intersect(lista2).ToList();

foreach (int item in filtro)
{
    Console.WriteLine(item);
}
// { 1, 2 }
```

### Union
- Produz a união de conjunto de duas sequências.
- Retorna IEnumerable<TSource>

```csharp=
List<int> lista = new List<int> { 1, 2, 3, 5, 7  };
List<int> lista2 = new List<int> { 1, 2};
List<int> filtro = lista.Union(lista2).ToList();

foreach (int item in filtro)
{
    Console.WriteLine(item);
}

// { 1, 2, 3, 5, 7 } 
```
