Supply a name to anonymous and call later in LINQ - c#

I have an int[] array = {34,65,3,65,3,2,68,8,4,2}. I want to divide this array into group of 5 and find average of each subgroup.

This syntax declares (implicitly) an array of the type returned by Avg() method:
new [] { Avrg = g.Avg() } // if g.Avg() returns int, it will be int[]
if you want to declare an array of anonymous types, you must do:
new[] { new { Avrg = g.Avg() } }
EDIT:
according to your edit, this code splits the array in groups of 5 elements and computes the average of them:
int[] array = { 34, 65, 3, 65, 3, 2, 68, 8, 4, 2 };
var avgGroups = from x in Enumerable.Range(0, array.Length)
group x by (x / 5) into g
select new { Avrg = g.Average(x => array[x]) };

You don't need to give it a name; the object you are creating is of type
IEnumerable<typeof(g.Avg)>
so you can enumerate through that object to get the value of g.Avg().

Probably you want to store type in array. For this you need to have like this
var v = from xyz in new [] { new {Avg = g.Avg()} }
select xyz;
Rather use this way,
var v = from xyz in new [] { g.Avg() }
select new {Avg = xyz};

Related

How to sort an array of strings of zeros and ones?

I am trying to sort an array of ints by it's binary form. for example if i have {1,2,3} i must convert them to binary then sort them based on how many 1 each has, if the number only has one 1 then it is number 1 and then comes the number that has two 1s in its binary form and so on.
i tried to use the following two methods but i couldn't do them due to errors and i don't understand. i searched all stackoverflow but can't figure it out, i am stuck for our here in this problem.
public static int[] xx = { 1, 2, 3, 4, 5, 6, 87, 8, 9, 7, 5, 24, 58, 63, 10, 11, 87, 20, 22, 90, 14, 17, 19, 21, 18, 24 };
public string[] ChangeToBinary(int[] data)
{
string[] binary = new string[data.Length];
var i = 0;
foreach (int d in data)
{
string newvalue = Convert.ToString(d, 2);
binary[i] = newvalue;
i++;
}
return binary;
}
public int[] Sort(string[] binaries)
{
Array.Sort(binaries, (x, y) => x.Count(z => z == '1') > y.Count(e => e == '1'));
string[] sorted = binaries.OrderBy(b => b.Count(z => z == '1') > b.Count(e => e == '1'));
}
the two lines inside the sort function i know that they are wrong in some point that i dont get can someone tell me how to do it ? i try to say to sort the elements of the array based on the least number of 1s in the element.
I won;t use both but i put them to show you what i wanted to use.
thanks in advance.
With a help of Convert and Linq you can easily count 1s:
int value = ...
ones = Convert
.ToString(value, 2) // Binary representation
.Count(c => c == '1'); // Count 1's
Having this done, let's sort the array:
int[] xx = ...
int[] sorted = xx
.OrderBy(value => Convert // criterium: see the code above
.ToString(value, 2)
.Count(c => c == '1'))
.ThenBy(value => value) // on tie e.g. 0b101 and 0b110 let's use value
.ToArray();
There are two different approaches to custom sorting:
You provide a comparison between any two elements. This is what Array.Sort takes. The comparison has to return an int with a value that's negative, zero or positive to indicate whether the first element is less than, equal to or greater than the second element. (Your lambda expression currently returns bool because you're using >.)
You provide a projection from one element, and the sort algorithm compares the results of that projection. That's what OrderBy does - but the lambda expression you're providing in the OrderBy compares the count of one element with the count from the same element.
I would suggest using the OrderBy approach, because that's much simpler. You're just trying to order by the count, so you just need to count the 1s in the element you're provided, and return that count:
string[] sorted = binaries.OrderBy(b => b.Count(z => z == '1')).ToArray();
Now your method is meant to return an int[] at the moment. Presumably it would convert each binary string back to an int. I'd suggest not doing that - instead change your Sort method to return the sorted string[]. You can then perform the conversion in another method, whether that's a separate method or the calling method.
That's the approach I'd take first, as the minimal change to your code - and as a way of understanding what's going on in the Sort and OrderBy methods. You can then potentially change to order the integers directly without ever directly creating an array of strings, as Dmitry suggests.
A solution for those of us who are just tip-toeing around Linq. More code but remember the linq is looping underneath.
public static int[] xx = { 1, 2, 3, 4, 5, 6, 87, 8, 9, 7, 5, 24, 58, 63, 10, 11, 87, 20, 22, 90, 14, 17, 19, 21, 18, 24 };
public class MyBinary
{
public string BinString { get; set; }
public int OneCount { get; set; }
public int OriginalInt { get; set; }
public MyBinary(string input, int count, int original)
{
OriginalInt = original;
BinString = input;
OneCount = count;
}
}
private List<MyBinary> SortByOnes(int[] input)
{
List<MyBinary> lst = new List<MyBinary>();
//The following will give a result First ordered by number of ones but also
// secondarily the original numbers
//just a bit of linq
int[] SortedArray = (from i in input orderby i select i).ToArray();
List <MyBinary> lstSorted = new List<MyBinary>();
int index = 0;
string[] Bin = new string[SortedArray.Count()];
foreach (int i in SortedArray)
{
Bin[index] = Convert.ToString(i, 2);
int oneCount = 0;
foreach (char c in Bin[index])
{
if (c == '1')
oneCount += 1;
}
//sends the binary string, the count of ones, and the original number
//to the constructor of MyBinary
lst.Add(new MyBinary(Bin[index], oneCount, i));
lstSorted = (from b in lst orderby b.OneCount descending select b).ToList();
index += 1;
}
return lstSorted;
}
//To use:
private void TestSort()
{
List<MyBinary> lst = SortByOnes(xx);
foreach (MyBinary b in lst)
{ Debug.Print($"{b.OneCount} - {b.BinString} - {b.OriginalInt}"); }
}

Handling of array operations in C sharp

I have been programming with Matlab for a couple of years. It handles operations on matrices and arrays quite easily.
Now, I am programming in C# and after reading for a while on sites such as http://msdn.microsoft.com/en-us/library/2s05feca.aspx and various other tutorial websites, I still have some questions.
In Matlab, something like this (written in a pseudo C# syntax) would work:
W[1][][] = new double[][]{{10,20,30},{40,50,60},};
where W is a 3 dimensional jagged array. The idea is that since the first dimension is defined (by 1 in this case), the assignation operation "understand" that the content of the 2 dimensional array provided is set to fill the two remainder dimensions of W. Then, how to get the same result or behaviour in C#?
Imagine the first dimension of W[][][] is a number associated with a city; the second, the age of every people living there and the third, their weight. Now lets have a portion of code that create a "calculation[][]" array containing ages and weights values. I want to assign the content of this array to W[1][][]. That is what I have failed to implement.
My objective is to do the equivalent of multiplication of matrices (and other relevant operations on matrices) using C#.
I read and read again a couple of explanations (can't list them all here) but it does not add up in my head, so I guess if someone could explain (again) how to manipulate multidimensional arrays in C#, it will help me understand how it works.
Thanks
This isn't a 3 dimensional array. This is just an array of an array.
I'm not really sure what you try to do.
Anyway, If I got u right u want to do something like this:
Ok, so if you need this for your example then I would recommend you a struct in order to do this easier.
If you want to understand Multidimensional Arrays then you should reed the following:
You defined your 'Multidimensional Array' like this:
double[][][] array;
That's not a 'Multidimensional Array'. This is an array (list) of an array of an array.
A real 'Multidimensional Array' is defined this (3 dimensions):
double[,,] array;
That's a difference :D
if u use the 'real Multidimensional Array' then u can do the above like this;
private static void Main(string[] args)
{
var raw = new double[,,]
{
{
{1, 2},
{3, 4}
},
{
{5, 6},
{7, 8}
}
};
Console.WriteLine(raw[0, 0, 0]); //1
Console.WriteLine(raw[1, 1, 0]); //7
Console.ReadKey();
}
And this would be the code for the array of an array of an array
var raw = new double[][][]
{
new double[][]
{
new double[]
{
1,
3
},
new double[]
{
2,
4
}
},
new double[][]
{
new double[]
{
5,
7
},
new double[]
{
6,
8
}
}
};
Console.WriteLine(raw[0][0][0]); //1
Console.WriteLine(raw[1][1][0]); //6
Console.ReadKey();
In your case (if you don't want to use a struct) than this array would be the better way!
A struct for your case would look like this:
private static void Main(string[] args)
{
var raw = new SampleDataStruct[2]
{
new SampleDataStruct
{
CityName = "New York", AgeWeight = new AgeWeightStruct[3]
{
new AgeWeightStruct{Age = 50,Weigth = 70},
new AgeWeightStruct{Age = 40,Weigth = 75},
new AgeWeightStruct{Age = 30,Weigth = 65}
}
},
new SampleDataStruct
{
CityName = "Berlin", AgeWeight = new AgeWeightStruct[3]
{
new AgeWeightStruct{Age = 50,Weigth = 65},
new AgeWeightStruct{Age = 40,Weigth = 60},
new AgeWeightStruct{Age = 30,Weigth = 55}
}
}
};
Console.WriteLine(raw.Where(st => st.CityName == "Berlin").ElementAtOrDefault(0).AgeWeight.Where(aw => aw.Age == 40).ElementAtOrDefault(0).Weigth); //Berlin -> Age = 40 -> Display Weight (60)
Console.WriteLine(raw.Where(st => st.CityName == "New York").ElementAtOrDefault(0).AgeWeight.Where(aw => aw.Age == 30).ElementAtOrDefault(0).Weigth); //New York -> Age = 30 -> Display Weight (65)
Console.ReadKey();
}
}
public struct SampleDataStruct
{
public string CityName;
public AgeWeightStruct[] AgeWeight;
}
public struct AgeWeightStruct
{
public int Age;
public int Weigth;
}
You can do it so:
Int32 firstDimensionSize = 3;
double[][][] matrix3D = new double[firstDimensionSize ][][];
matrix3D[1]= new double[][]
{
new double[]{10,20,30},
new double[]{40,50,60},
};
Because matrix3D is an array of arrays of arrays. Each its element is double[][] - 2D jagged array. Just don't forget that matrix3D[0] and matrix3D[2] will be uninitialized - null.
var W = new double[][][]
{
new double[][]{
new double[] {1,2,3}, new double[] {4,5,6}
},
new double[][]{
new double[] {7,8,9}, new double[] {10,11,12}
}
};
Alternatively, you can use a double[,,] if the dimensions are the same:
var W = new double[,,]
{
{
{1,2,3}, {4,5,6}
},
{
{7,8,9}, {10,11,12}
}
};

How can I extract 3 random values from an array?

I build my MyObject array with :
MyObject[] myObject = (from MyObject varObj in MyObjects
select varObj).ToArray();
and now, I'd like to extract 3 random MyObject from this array! How can I do it on C#?
Of course, if array lenght is <3 I need to extract all objects!
You can do this via Linq:
Retrieve the items in random order (see Jon Skeet's answer to this SO question)
Select Top(3) of the resulting list using the Take operator
As an example, select 3 processes at random:
var ps = (from p in Process.GetProcesses() orderby Guid.NewGuid() select p).Take(3);
You can also use random.Next() instead of Guids (since strictly speaking, as pointed out by LukeH, Guids are unique, but not random).
MyObject[] myObject = ...;
int upper = 1;
if (myObject.Length > 1)
{
Random r = new Random();
upper = Math.Min(3, myObject.Length);
for (int i = 0; i < upper; i++)
{
int randInd = r.Next(i, myObject.Length);
MyObject temp = myObject[i];
myObject[i] = myObject[randInd];
myObject[randInd] = temp;
}
}
now take elements of the array from 0 to upper.
using Random class of C# you can get random int which are less than a particular number which in your case will be the size of myObject
I am not sure you want unique or they can duplicate.
How about?
Random r = new Random();
int item1 = r.Next(0, myObject.Length);
int item2 = r.Next(0, myObject.Length);
int item3 = r.Next(0, myObject.Length);
var result1 = myObject[item1];
var result2 = myObject[item2];
var result3 = myObject[item3];
No Linq or anything, but it gets the job done.
What about this:
var random = new Random();
var objs = new Object[] { 1, 2, 3, 4, 5, 6, 7, 8 };
var result = objs.OrderBy(o => random.Next(Int32.MaxValue)).Take(3);
A little bit more creative.
var list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 1, 2, 3, 44, 5, 6 };
Random random = new Random();
var results = list.OrderBy(i => random.Next()).Take(3);
Output:
results: {int[3]}
[0]: 3
[1]: 2
[2]: 5

Filtering in LINQ

From the given setup
IEnumerable<int> one = new int[] { 1, 2, 3, 4, 5, 6, 7 };
IEnumerable<int> two = new int[] { 12, 34, 56, 7, 8 };
MySet[] sets
= new MySet[]
{
new MySet{ MySetID =100, MySubSet=new MySubSet{SubSet=new List<int>(one),
SubSetID=1212}},
new MySet{ MySetID =101, MySubSet=new MySubSet{SubSet=new List<int>(two),
SubSetID=1414}}
};
How can i filter out even numbers from "SubSet"s
var GetSet =
from mysets in sets
where (P => mysets.MySubSet.SubSet.FindAll(???? ))
select mysets;
Is this what you want? Your question is rather confusingly worded, but I believe you are looking for something like this:
var query = from mySet in sets
select new MySet {
MySetID = mySet.ID,
MySubSet = new MySubSet {
SubSet = mySet.MySubSet.SubSet.Where(p => p % 2 == 0).ToList(),
SubSetID = mySet.MySubSet.SubSetID
}
};
So I am interpreting your question to mean that you want to filter out the even numbers from MySubSet.SubSet in each instance of MySet.

Conversion of System.Array to List

Last night I had dream that the following was impossible. But in the same dream, someone from SO told me otherwise. Hence I would like to know if it it possible to convert System.Array to List
Array ints = Array.CreateInstance(typeof(int), 5);
ints.SetValue(10, 0);
ints.SetValue(20, 1);
ints.SetValue(10, 2);
ints.SetValue(34, 3);
ints.SetValue(113, 4);
to
List<int> lst = ints.OfType<int>(); // not working
Save yourself some pain...
using System.Linq;
int[] ints = new [] { 10, 20, 10, 34, 113 };
List<int> lst = ints.OfType<int>().ToList(); // this isn't going to be fast.
Can also just...
List<int> lst = new List<int> { 10, 20, 10, 34, 113 };
or...
List<int> lst = new List<int>();
lst.Add(10);
lst.Add(20);
lst.Add(10);
lst.Add(34);
lst.Add(113);
or...
List<int> lst = new List<int>(new int[] { 10, 20, 10, 34, 113 });
or...
var lst = new List<int>();
lst.AddRange(new int[] { 10, 20, 10, 34, 113 });
There is also a constructor overload for List that will work... But I guess this would required a strong typed array.
//public List(IEnumerable<T> collection)
var intArray = new[] { 1, 2, 3, 4, 5 };
var list = new List<int>(intArray);
... for Array class
var intArray = Array.CreateInstance(typeof(int), 5);
for (int i = 0; i < 5; i++)
intArray.SetValue(i, i);
var list = new List<int>((int[])intArray);
Interestingly no one answers the question, OP isn't using a strongly typed int[] but an Array.
You have to cast the Array to what it actually is, an int[], then you can use ToList:
List<int> intList = ((int[])ints).ToList();
Note that Enumerable.ToList calls the list constructor that first checks if the argument can be casted to ICollection<T>(which an array implements), then it will use the more efficient ICollection<T>.CopyTo method instead of enumerating the sequence.
The simplest method is:
int[] ints = new [] { 10, 20, 10, 34, 113 };
List<int> lst = ints.ToList();
or
List<int> lst = new List<int>();
lst.AddRange(ints);
In the case you want to return an array of enums as a list you can do the following.
using System.Linq;
public List<DayOfWeek> DaysOfWeek
{
get
{
return Enum.GetValues(typeof(DayOfWeek))
.OfType<DayOfWeek>()
.ToList();
}
}
in vb.net just do this
mylist.addrange(intsArray)
or
Dim mylist As New List(Of Integer)(intsArray)
You can do like this basically:
int[] ints = new[] { 10, 20, 10, 34, 113 };
this is your array, and than you can call your new list like this:
var newList = new List<int>(ints);
You can do this for complex object too.
You can just give it try to your code:
Array ints = Array.CreateInstance(typeof(int), 5);
ints.SetValue(10, 0);
ints.SetValue(20, 1);
ints.SetValue(10, 2);
ints.SetValue(34, 3);
ints.SetValue(113, 4);
int[] anyVariable=(int[])ints;
Then you can just use the anyVariable as your code.
I know two methods:
List<int> myList1 = new List<int>(myArray);
Or,
List<int> myList2 = myArray.ToList();
I'm assuming you know about data types and will change the types as you please.
Just use the existing method.. .ToList();
List<int> listArray = array.ToList();
KISS(KEEP IT SIMPLE SIR)
I hope this is helpful.
enum TESTENUM
{
T1 = 0,
T2 = 1,
T3 = 2,
T4 = 3
}
get string value
string enumValueString = "T1";
List<string> stringValueList = typeof(TESTENUM).GetEnumValues().Cast<object>().Select(m =>
Convert.ToString(m)
).ToList();
if(!stringValueList.Exists(m => m == enumValueString))
{
throw new Exception("cannot find type");
}
TESTENUM testEnumValueConvertString;
Enum.TryParse<TESTENUM>(enumValueString, out testEnumValueConvertString);
get integer value
int enumValueInt = 1;
List<int> enumValueIntList = typeof(TESTENUM).GetEnumValues().Cast<object>().Select(m =>
Convert.ToInt32(m)
).ToList();
if(!enumValueIntList.Exists(m => m == enumValueInt))
{
throw new Exception("cannot find type");
}
TESTENUM testEnumValueConvertInt;
Enum.TryParse<TESTENUM>(enumValueString, out testEnumValueConvertInt);

Categories

Resources