# c# – Is it possible to express this code in LINQ? – Education Career Blog

I’m reading a C# book for beginners, and in every end of the chapter, there are exercises to be answered based on the lessons tackled.

One of those exercises goes this way: (not the exact wordings)

Write a program that will accept an int as the array length, and the values for the array.
Then will print:
0” if the array is not sorted in ascending way.
1” if it is sorted. And,
2” if it is sorted, but there are duplicates.

Example:

``````// Sorted
Input: 1, 2, 3, 5
Print: 1

// Not sorted
Input: 2, 1, 3, 6
Print: 0

// Sorted, but with duplicates
Input: 2, 2, 3, 7
Print: 2
``````

I don’t know if my logic here is absolute, but somehow it is working,
and I done it in my way using this code:

``````int arrayLength = 0;
int prev, next;
int sortStatus = 1;

Console.Write("Input array Length: ");
int ar = new intarrayLength;

for (int x = 0; x < arrayLength; x++)
{
Console.Write("Input {0} value: ", (x+1).ToString());
}

for (int x = 0; x < ar.Length-1; x++)
{
prev = (int)arx;
next = (int)arx + 1;

if (next < prev)
sortStatus = 0;
if (next == prev)
sortStatus = 2;
}

Console.Write(sortStatus.ToString());
``````

Is it possible to express this in LINQ? How?

,

``````if (ar.SequenceEqual(ar.OrderBy(x => x)))
{
if (ar.Distinct().Count() == ar.Length)
return 1;
else
return 2;
}
else
{
return 0;
}
``````

,

A pure LINQ alternative … (for academic interest only (but probably still faster than the accepted answer!)

``````var input = new int { 1, 2, 3, 4, 5 };

var output = input.Zip(input.Skip(1), (a, b) => new {a=a, b=b})
.Aggregate(1, (status, x) => status == 0 ? 0 : ((x.a > x.b ? 0 : (x.a == x.b ? 2 : status))));
``````

,

As a note, your expressed non-LINQ logic has a flaw.

``````if (next < prev)
sortStatus = 0;
if (next == prev)
sortStatus = 2;
``````

Your rule says that the array must be sorted ascending but have duplicates in order to get an output of 2. However, your logic will return 2 for `{ 1, 9, 7, 7 }`.

Another way to write your code might be the following. (This is not using LINQ, but this is too long to post as a comment to your question.)

``````static int EvaluateArray(int array)
{
int? lastItem = null;
bool match = false;
foreach (int item in array)
{
if (item < lastItem)
return 0;
else if (item == lastItem)
match = true;

lastItem = item;
}

if (match)
return 2;

return 1;
}
``````

In this method, we will early-return as soon as we have an item less than the previous item. Otherwise, we will set a boolean if we come across a matching value. At the end of the loop, we know the array is sorted ascending. The only thing left is check if there was a match.

,

Untested.

``````IEnumerable<int> signs =
from i in Enumerable.Range(0, ar.Length).Skip(1)
select ari-1.CompareTo(ari);

int result =
signs.Any(sign => sign < 0) ? 0 :
signs.All(sign => 0 < sign) ? 1 :
2;
``````

Also untested:

``````int minSign = !ar.Skip(1).Any() ? 1 :
(
from i in Enumerable.Range(0, ar.Length).Skip(1)
select ari-1.CompareTo(ari)
).TakeWhile(x => 0 <= x).Min();

int result =
minSign < 0 ? 0 :
0 < minSign ? 1 :
2;
``````