How do I use LINQ to query an array of numbers to get the highest value between start index and end index.
int[] numbers = { 1, 2, 3, 4 ,5 ,6 ,7 ,8 ,9 ,8 ,7 ,6, 5 ,4 ,3 ,2 ,1};
I want to find the Max value between numbers[5] and numbers[8]
Thanks
Mike
You need to skip four elements, then take the max of the next four (#5..#8, inclusive):
var begin = 5;
var end = 8;
var res = numbers.Skip(begin-1).Take(end-begin+1).Max();
How about:
numbers.Skip( 5 ).Take( 4 ).Max();
Something like this: ?
numbers.Where((n, i) => i >= 5 && i <= 8).Max();
Related
I haven't been able to find anything on google.
I have this piece of code:
Random r = new Random();
int[] output = Enumerable.Range(0, 11).Select(x => x / 2).OrderBy(x => r.Next()).ToArray();
and I am having trouble actually understanding what each element does.
It generates a range of numbers and elements between 0 and 11.
But what does the select(x => x / 2) do ? does it just make pairs of elements,
I know what the whole thing spits out, an array with pairs of numbers, with a single number which has no pair.
but it is a bit above me to fully understand it ?
( is this even okay to ask on here ?? or should I delete the question again ? )
It generates a range of numbers and elements between 0 and 11. But what does the select(x => x / 2) do ? does it just make pairs of elements.
No, Select does what in some programming languages is known as map. It is called on an IEnumerable<T> and has as parameter Func<T,U> a function, and it produces an IEnumerable<U> where each element if the given IEnumerable<T> is processes through the function and the result is emitted in the result.
So in this case, it will take a range from 0 to (excluding) 11, and for each of those integers, perform an integer divsion by two:
csharp> Enumerable.Range(0, 11);
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
csharp> Enumerable.Range(0, 11).Select(x => x/2);
{ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5 }
Since:
{ 0/2, 1/2, 2/2, 3/2, 4/2, 5/2, 6/2, 7/2, 8/2, 9/2, 10/2 }
== { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5 }
Later then that IEnumerable<int> is reordered (using the OrderBy) by using pseudo-random numbers (so we shuffle them) and converted into a list.
.Range(0, 11) // generate a sequence of integers starting at 0 and incrementing 11 times (i.e. the values 0 up to and including 10)
.Select(x => x / 2) // divide each of those values from previous result by 2 and return them
.OrderBy(x => r.Next()) // then order them randomly using a random number
.ToArray(); // return the end result as an array
Think of Select as doing a transformation to each element of the IEnumerable.
For example, let's say we have a list like this:
0 1 2 3 4 5 6 7 8 9 10
Then we call .Select(x => x / 2), we are saying that for each element x in the list, do the following transformation:
x / 2
We divide each element in the list by two:
Original Transformation Result
0 0 / 2 0
1 1 / 2 0
2 2 / 2 1
3 3 / 2 1
4 4 / 2 2
5 5 / 2 2
6 6 / 2 3
7 7 / 2 3
8 8 / 2 4
9 9 / 2 4
10 10 / 2 5
We get
0 0 1 1 2 2 3 3 4 4 5 5
What Select() does is that it evaluates the given expression for every element of the Enumerable it's called on (the original list), and returns a new Enumerable with the results.
For a list:
[2, 4, 6]
it's going to return:
[2/2, 4/2, 6/2]
where / means "division", so the result of the Select() (not the entire LINQ chain) will be:
[1, 2, 3]
Analogously, if your source list is:
words = ["dog", "child", "building"]
And you call:
words.Select(word => word.Length)
you get a list of all the lengths of the strings in the list in order:
[3, 5, 7]
I am looking to create a program like the following (c# btw):
int[] arr = new int[9]
//some code that puts values 1, 0, or 2 in each array element
for(int i = 0; i < arr.Length; i++)
{
if (arr[i] == arr[i + 3]) { return true; }
}
So, for each value in the array I am applying a formula that does something with that value and the value 3 indexes ahead of it. Of course, this runs into an out of range exception once i+3>8.
What I'd like to do is if the the desired index is out of range then loop the index values back around to the beginning of the array. So, in an array of length 9 where the last index is 8, if on a given loop i = 7, and i+3 then = 10, I would like i+3 to 'become,' by whatever means, 1, and then when i = 8, and i+3 = 11, I want i+3 to become 2.
So, the index pairs being evaluated would be something like:
i , i+3
0 3
1 4
2 5
3 6
4 7
5 8
6 0
7 1
8 2
how can I go about doing this?
Thanks for any help.
Use the modulo operator like this:
if (arr[i] == arr[(i + 3) % arr.Length]) { return true; }
You could try the following expression inside your if statement.
arr[i] == arr[(i + 3) % arr.Length];
The % Operator
Divides the value of one expression by the value of another, and
returns the remainder.
i am learning C# and LINQ so i am sorry for that question.
how to type in linq to group the same elements in certain array, but when they group it they see if the count of the group is greater than 2 and then division it by 2 and return the value of the group count and then add it to int
what i want the linq to do in code :
s => s > 2
s /= 2
return s;
my original code is that:
int n = Convert.ToInt32(Console.ReadLine());
string[] userinput = Console.ReadLine().Split(' ');
int[] socks = new int[n];
socks = Array.ConvertAll(userinput, Int32.Parse);
var result = socks.GroupBy(s => s > 2).ToArray(); //This is the line which i want help
int total = 0;
foreach (var group in result)
{
total += group.Count();
Console.WriteLine(group.Count());
}
Lets assume we have 10 kinds of socks. which are 10,20,30,40,50,60,70, 80,90,100
now in the first line i enter the number of the socks i have so for example its 5.
in the second line i enter the 5 socks kinds for example. 10 10 20 20 30
now i want the linq code to define that there is 3 keys here which are 10 20 30, the 10 key has more than only 1 count it has 2. the same for 20 but the 30 only have 1 so lets forget about the 30. now the count of they key of each one of them is 2 so lets divide it by 2 for each one then add the divided number to the total so 2/2 for each one equals 1 so total = 2 (this is the my expected output)
If understand you right, you want to count pairs of socks:
int total = socks
.GroupBy(x => x)
.Sum(chunk => chunk.Count() / 2);
According to your example:
[10, 10, 20, 20, 30]
after grouping socks by their sizes
10: [10, 10] - 2 socks, 1 pair (you've put it as "divide by 2")
20: [20, 20] - 2 socks, 1 pair
30: [30] - 1 sock, 0 pairs
-------------------------------
2 pairs in total (the expected value)
My example (from the comments to the question)
1, 2, 2, 2, 3, 4, 5, 5
should return 2 as well (we have 2 pairs: of size 2 and 5)
In case you want to get pairs:
var pairs = socks
.GroupBy(x => x)
.Select(chunk => new {
size = chunk.Key,
count = chunk.Count() / 2, });
//.Where(pair => pair.count > 0); // you may want to filter out single socks
I have a list called “sum” which contains integer values between 0, 1, 2, 3, 4 and 5. I want to make another list called “average” which contains the average value by dividing every element of the sum list by 5 and add the results to the same element of the average list.
My problem is I am using the code:
List<int> average = sum.Select(x => x/5).ToList();
But it does not give me a correct results as C# decides automatically how to round the result to 0 or 1. But for example when I give the results to excel, it gives me a different results.
I need to manually get every element of my sum list and divide it by five, then decide if the answer is greater or equal to 0.5, round it up to 1. And if the result is less than 0.5 round it to 0.
List<int> average = sum.Select( x => (int)Math.Round(x/5.0) ).ToList();
However, if you really want an average of the items:
int average = Math.Round( sum.Average() );
var average = sum.Select(x => (int)(x / 5.0 + 0.5)).ToList();
or using Math.Round:
var average = sum.Select(x => (int)Math.Round(x / 5.0)).ToList();
var average = sum.Select(x => (x / 5.0) >= 0.5 ? 1 : 0).ToList();
What is an efficient way of generating N unique numbers within a given range using C#? For example, generate 6 unique numbers between 1 and 50. A lazy way would be to simply use Random.Next() in a loop and store that number in an array/list, then repeat and check if it already exists or not etc.. Is there a better way to generate a group of random, but unique, numbers?
To add more context, I would like to select N random items from a collection, using their index.
thanks
Take an array of 50 elements: {1, 2, 3, .... 50}
Shuffle the array using any of the standard algorithms of randomly shuffling arrays. The first six elements of the modified array is what you are looking for. HTH
For 6-from-50, I'm not too sure I'd worry about efficiency since the chance of a duplicate is relatively low (30% overall, from my back-of-the-envelope calculations). You could quite easily just remember the previous numbers you'd generated and throw them away, something like (pseudo-code):
n[0] = rnd(50)
for each i in 1..5:
n[i] = n[0]
while n[1] == n[0]:
n[1] = rnd(50)
while n[2] == any of (n[0], n[1]):
n[2] = rnd(50)
while n[3] == any of (n[0], n[1], n[2]):
n[3] = rnd(50)
while n[4] == any of (n[0], n[1], n[2], n[3]):
n[4] = rnd(50)
while n[5] == any of (n[0], n[1], n[2], n[3], n[4]):
n[5] = rnd(50)
However, this will break down as you move from 6-from-50 to 48-from-50, or 6-from-6, since the duplicates start getting far more probable. That's because the pool of available numbers gets smaller and you end up throwing away more and more.
For a very efficient solution that gives you a subset of your values with zero possibility of duplicates (and no unnecessary up-front sorting), Fisher-Yates is the way to go.
dim n[50] // gives n[0] through n[9]
for each i in 0..49:
n[i] = i // initialise them to their indexes
nsize = 50 // starting pool size
do 6 times:
i = rnd(nsize) // give a number between 0 and nsize-1
print n[i]
nsize = nsize - 1 // these two lines effectively remove the used number
n[i] = n[nsize]
By simply selecting a random number from the pool, replacing it with the top number from that pool, then reducing the size of the pool, you get a shuffle without having to worry about a large number of swaps up front.
This is important if the number is high in that it doesn't introduce an unnecessary startup delay.
For example, examine the following bench-check, choosing 10-from-10:
<------ n[] ------>
0 1 2 3 4 5 6 7 8 9 nsize rnd(nsize) output
------------------- ----- ---------- ------
0 1 2 3 4 5 6 7 8 9 10 4 4
0 1 2 3 9 5 6 7 8 9 7 7
0 1 2 3 9 5 6 8 8 2 2
0 1 8 3 9 5 6 7 6 6
0 1 8 3 9 5 6 0 0
5 1 8 3 9 5 2 8
5 1 9 3 4 1 1
5 3 9 3 0 5
9 3 2 1 3
9 1 0 9
You can see the pool reducing as you go and, because you're always replacing the used one with an unused one, you'll never have a repeat.
Using the results returned from that as indexes into your collection will guarantee that no duplicate items will be selected.
var random = new Random();
var intArray = Enumerable.Range(0, 4).OrderBy(t => random.Next()).ToArray();
This array will contain 5 random numbers from 0 to 4.
or
var intArray = Enumerable.Range(0, 10).OrderBy(t => random.Next()).Take(5).ToArray();
This array will contain 5 random numbers between 0 to 10.
int firstNumber = intArray[0];
int secondNumber = intArray[1];
int thirdNumber = intArray[2];
int fourthNumber = intArray[3];
int fifthNumber = intArray[4];
For large sets of unique numbers, put them in an List..
Random random = new Random();
List<int> uniqueInts = new List<int>(10000);
List<int> ranInts = new List<int>(500);
for (int i = 1; i < 10000; i++) { uniqueInts.Add(i); }
for (int i = 1; i < 500; i++)
{
int index = random.Next(uniqueInts.Count) + 1;
ranInts.Add(uniqueInts[index]);
uniqueInts.RemoveAt(index);
}
Then randomly generate a number from 1 to myInts.Count. Store the myInt value and remove it from the List. No need to shuffle the list nor look to see if the value already exists.
instead of using List use Dictionary!!
In case it helps anyone else, I prefer allocating the minimum number of items necessary. Below, I make use of a HashSet, which ensures that new items are unique. This should work with very large collections as well, up to the limits of what HashSet plays nice with.
public static IEnumerable<int> GetRandomNumbers(int numValues, int maxVal)
{
var rand = new Random();
var yieldedValues = new HashSet<int>();
int counter = 0;
while (counter < numValues)
{
var r = rand.Next(maxVal);
if (yieldedValues.Add(r))
{
counter++;
yield return r;
}
}
}
generate unique random nos from 1 to 40 :
output confirmed :
class Program
{
static int[] a = new int[40];
static Random r = new Random();
static bool b;
static void Main(string[] args)
{
int t;
for (int i = 0; i < 20; i++)
{
lab: t = r.Next(1, 40);
for(int j=0;j<20;j++)
{
if (a[j] == t)
{
goto lab;
}
}
a[i] = t;
Console.WriteLine(a[i]);
}
Console.Read();
}
}
sample output :
7
38
14
18
13
29
28
26
22
8
24
19
35
39
33
32
20
2
15
37