How to cast object[] to double[][] in C# - c#

I have something like
var a = new object[2]
{
new double[1] { 0.5 },
new double[1] { 0.5 }
}
And I want to cast this to double[][].
I tried (double[][])a and a.Cast<double[][]>() but it didnt work

Your attempt of doing a.Cast<double[][]>() is almost correct. You can use:
double[][] b = a.Cast<double[]>().ToArray();
Explanation:
The problem is that the elements of your list are double[]s, but they are statically typed as object. To change the static type of a list's elements, you use LINQ's Cast<T>.
Cast<T> takes the type of the element as T, not the type of the resulting list (this is why your attempt to use Cast<double[][]>failed). Cast<double[]> yields an IEnumerable<double[]>.
To convert this IEnumerable<double[]> to an array of double[] (i.e., a double[][]), we can use LINQ's ToArray().
Note that this will
create a new outer array (i.e., object.ReferenceEquals(a, b) is false), but
the new outer array will reference the same inner arrays (i.e., object.ReferenceEquals(a[0], b[0]) is true).

You can use LINQ double[][] b = a.Select(x => (double[])x).ToArray();
another way is to use Array.ConvertAll method, It takes a callback function which is called for each element in the given array.
double[][] b = Array.ConvertAll(a, x => (double[])x);

Related

How to Create A Merged Array from 3 Arrays with LINQ which is not zipped but based on Content Equality

I have three Arrays which should be merged into one result via Linq:
int?[] list1 = {0,1,2,3,4};
int?[] list2 = {2,3,4,5};
int?[] list3 = {3,4};
Result:
var result=
{
(0,null,null),
(1,null,null),
(2,2,null),
(3,3,3),
(4,4,4),
(null,5,null)
}
Let's start by defining our input in a little more generic terms: a list of a list of integers. Since we don't need to modify these collections, we'll use the simplest interface that gives us what we need, IEnumerable<T>. That means our input is going to be: IEnumerable<IEnumerable<int?>>. Our output is going to be the same.
So now, let's define a prototype for the method that will do the work:
public static IEnumerable<IEnumerable<int?>> Merge(IEnumerable<IEnumerable<int?>> source) { //... }
Immediately I've noticed something: we don't really need to use int? since all we care about is checking equality, and all types support that, so we can make this method generic, and support any type:
public static IEnumerable<IEnumerable<T>> Merge<T>(IEnumerable<IEnumerable<T>> source) { //... }
Now let's start with the implementation, first we will need to compute every distinct value from all the lists:
source.SelectMany(x=>x).Distinct()
Now, for each of those values we need to return a collection with an item for each item in the original 'super list':
source.SelectMany(x=>x).Distinct().Select(x=>source.Select(y=> //...
So what do we need in that final Select lambda? We have x as each distinct integer (or technically T), and y as each original collection. We want the value x if the y collection contains x, otherwise, null (or to allow value types too, default(T). We can do that with a ternary:
source.SelectMany(x=>x).Distinct().Select(x=>source.Select(y=>y.Contains(x)?x:default(T)));
Putting it all together:
public static IEnumerable<IEnumerable<T>> Merge<T>(this IEnumerable<IEnumerable<T>> source)
{
return source
.SelectMany(x=>x)
.Distinct()
.Select(x=>source
.Select(y=>y.Contains(x)?x:default(T)));
}
And you can call it like so:
int?[] list1 = {0,1,2,3,4};
int?[] list2 = {2,3,4,5};
int?[] list3 = {3,4};
var result = new []{ list1, list2, list3 }.Merge();
Console.WriteLine(string.Join(Environment.NewLine, result.Select(t=>string.Join(",", t))));
First put all your arrays into one:
var lists = new[] { list1, list2, list3 };
Now loop all possible numbers and check if check if they are contained in the appropriate arrays. If so, you can add that number to your result, otherwise add null:
var result = new List<List<int?>>();
for(int i = 0; i < 6; i++)
{
result.Add(new List<int?>());
for(int j = 0; j < 3; j++)
{
if(lists[j].Contains(i))
result[i].Add(i);
else
result[i].Add(null);
}
}
I suppose this is pretty straightforward. Doing this is linq will just overcomplicate things, looks ugly and is hard to debug and understand. I doubt it´s a good idea to do so.

Iterate over list of iterators linq

List enumerators not working in case when they are put in a list. For example in case of two lists (two enumerators)
public void test()
{
var firstList = new List<int>() { 1, 2, 3 };
var secondList = new List<int>() { 4, 5, 6 };
var lists = new List<List<int>>();
lists.Add(firstList);
lists.Add(secondList);
// Not working
var iterators = lists.Select(x => x.GetEnumerator()).ToList();
iterators.ForEach(x => x.MoveNext());
iterators.ForEach(x => Console.WriteLine(x.Current));
// Working
var firstIterator = iterators[0];
var secondIterator = iterators[1];
firstIterator.MoveNext(); secondIterator.MoveNext();
Console.WriteLine(firstIterator.Current);
Console.WriteLine(secondIterator.Current);
}
the first part is not working and it prints 0 0, while the second part is working and it prints 1 4.
I don't understand what is mistake with the first part and how it can be solved.
This is because the List<T>.GetEnumerator method returns a List<T>.Enumerator mutable struct.
When you assign it to a variable and call MoveNext and Current, it works. But when passed to delegate, it is passed by value, hence the delegate receives a copy so calling MoveNext has no effect of the original struct Current.
Just one of the side effects of the mutable structs.
If you change
x => x.GetEnumerator()
to
x => (IEnumerator<int>)x.GetEnumerator()
or
x => x.AsEnumerable().GetEnumerator()
both snippets will work because now the iterators will contain a boxed references of the returned structs.
Its because you run 2 separate .ForEach() in the not working part. Do both actions in 1 foreach (MoveNext(), then print). MoveNext will not be remembered in a .Foreach() for a good explaination: Go to this answer
This:
iterators.ForEach(x => x.MoveNext());
iterators.ForEach(x => Console.WriteLine(x.Current));
Becomes:
iterators.ForEach(x => { x.MoveNext(); Console.WriteLine(x.Current); });
List's enumerator is implemented as a value type (source code):
iterators[0].GetType().IsValueType // true
That means - iterators are passed by value when you are passing them to the methods (i.e. copy of iterator is passed instead of passing a reference to iterator instance). ForEach method simply executes an action in a loop:
iterators.ForEach(copy => copy.MoveNext());
Action delegate is a method, so you are passing a copy of each iterator to this method. So original iterators remain unchanged. And when you call ForEach second time, again, copies of original untouched iterators are passed there:
iterators.ForEach(newCopy => Console.WriteLine(newCopy.Current));
But original iterators are in the initial state (before the first item) that is why you see default values of integer type when you read Current value.
You can either work with single copy of iterator:
iterators.ForEach(copy => { copy.MoveNext(); Console.WriteLine(copy.Current); });
Or box value type to pass it by reference (note that type of iterators list will change):
var iterators = lists.Select(x => (IEnumerable<int>)x.GetEnumerator()).ToList();

Why can the anonymous type be changed if it is supposed to be immutable?

I thought I had a good understanding of the anonymous type, but this small code snippet has left me a little confused:
string[] arr = { "Agnes", "Allan", "Benny" };
var result = arr.Where(a => a.StartsWith("A")).Select(a => a);
// Why can I do the below, if arr is immutable?
result = arr.Where(a => a.EndsWith("n")).Select(a => a);
What I don't understand is why I am allowed to assign a second value to result. I mean isn't the idea of anonymous types being immutable, that they cannot be changed after they have got their initial value?
First, there is no anonymous type involved.
This string[] arr = { "Agnes", "Allan", "Benny" }; is an array creation expression.
result is IEnumerable<string> and in both LINQ statements you are just creating a query.
This is what is going on:
array creation expression
string[] arr = { "Agnes", "Allan", "Benny" };
query arr and returns IEnumerable<string>
var result = arr.Where(a => a.StartsWith("A")).Select(a => a);
assigns results a new query on arr returning IEnumerable<string>
result = arr.Where(a => a.EndsWith("n")).Select(a => a);
As far as, for understanding immutability, think of String also see this article: Immutable types: understand their benefits and use them
You have an anonymous type when you do something like:
var anon = new { X = 5, Y = 6 };
There are some pretty simple rules: you can't express the type of an anonymous type (so often you use var)... there must be a new {... You must give a name to the properties and a value X = 5.
What you are doing is creating an array of string[] using an array initializer. You are even writing it:
string[] arr = ...
And you aren't modifying anything... result is another variable, referencing an IEnumerable<> (a new object you are creating) and then referencing another IEnumerable<> At the end of your code you have 6 objects (a little more, but we will ignore some invisible objects):
The array referenced by arr (and referenced by the two IEnumerable<>)
The second IEnumerable<>, referenced by result, that has a reference to arr
The first IEnumerable<>, not referenced by anyone (the GC will collect it before or later), that has a reference to arr
3x string, all referenced by arr. Note that IEnumerable<> are "lazy", so they don't contain any reference to any string
The result variable is assigned twice, to two different IEnumerable<>. It is nearly always legal to reassign variables (exception are readonly fields). it is clearly legal to do:
string foo = "Foo";
foo = "Bar";
Another useful concept to understand is the difference between type, instance and variable.
Simplifying, type is like a blueprint, it describes what an instance of the type will look like:
class Car
{
public int Doors {get; set;}
public string EngineType { get; set;}
}
The code above describes type. You can make many instances of this type:
Car truck = new Car { Doors = 2, EngineType = "BigEckingEngine" };
Car pickup = new Car { Doors = 5, Engine Type = "4 cylinder" };
etc...
Note how variables truck and pickup house your instances. But variables are just that, they can house any instance of their respective type, so while it does not make much sense you can do this:
Car tmp = truck;
truck = pickup;
pickup = tmp;
The instances themselves has not changed. But the variables now hold different instances.
The instances of this example Car class above are mutable. So you can do this:
pickup.Doors = 99;
Should the type be immutable, you would not be able to do that, but you are still can do variable assigning as in the example with the tmp variable freely, regardless of type being mutable or not, because such assignment do not change instances.
As noted, your example does not contain an anonymous type, but even if it did, it does not involve any kind of mutation you are asking about.
LINQ methods like Where() and Select() don't change the underlying array. It creates a new object. The created result is of type IEnumerable<string>, LINQ just filters the array so if you will iterate over it later, you will just get values that match Where and Select but your arr object will remain unchanged.
It's worth expanding the other answers to show that a CONCRETE resolution of a LINQ query is not the same as a IEnumerable<T> and that neither have anything to do with anonymous type immutability.
If you created the following array of anonymous types:
var arr = new[] { new { Name = "Agnes"}, new { Name = "Allan" }, new { Name = "Benny" }};
arr.GetType().Dump();
var result = arr.Where(a => a.Name.StartsWith("A")).Select(a => a)
result = arr.Where(a => a.Name.EndsWith("n")).Select(a => a);
result.Dump();
in my case,
<>f__AnonymousType0`1[System.String][]
and
"Allan"
are respectively outputted, because result type is actually
System.Linq.Enumerable+WhereSelectArrayIterator`2[
<>f__AnonymousType0`1[System.String],
<>f__AnonymousType0`1[System.String]]
In addition, if I try to resolve the IEnumerable and then re-update the result:
var result = arr.Where(a => a.Name.StartsWith("A")).Select(a => a).ToList();
result = arr.Where(a => a.Name.EndsWith("n")).Select(a => a).ToList();
I once again get an output of
"Allan"
However, in this case my result type has been reevaluated to
System.Collections.Generic.List`1[<>f__AnonymousType0`1[System.String]]
since ToList() is creating a new collection. I can technically add and remove to that collection at will since the collection itself is quite willing to be mutated.
Finally, that does not mean that the underlying anonymous type object is not immutable!
result.First ().Name = "fail";
Will fail, regardless of result being a list with the following error:
Property or indexer 'AnonymousType#1.Name' cannot be assigned to -- it
is read only
precisely because it is immutable.

Find all elements that are lesser than or equal to the value

I'm new in c# and I have an array like this:
int[] cost = new int[] {10, 15, 20, 30, 50};
What is the simplest code to find/get all values that are lesser than or equal to the value?
The given value is 29, would return 20, 15, and 10.
Here's one of the simplest things you can do for this:
var resultArray = cost.Where(item => item <= 29).ToArray();
Here's another:
var resultArray = Array.FindAll(cost, item => item <= 29);
The first option uses an extension methods named Where that operates on IEnumerable, which arrays implement. IEnumerable is an interface for a sequence of elements that can be stepped through one after the other.
The second option uses FindAll, which is actually built in to the Array class.
The item => item <= 29 stuff is lambda notation. It's a highly concise way of defining a function on the spot.
This way of writing an anonymous function on the spot is saying
Where or FindAll each receive an argument that is an anonymous function, and we will define that argument that is an anonymous function right here in the actual call to Where() or FindAll().
The anonymous function itself receives as its own one argument an element, which we'll call item (the name could be anything, it could also be x). This item is an individual element of the Array (or IEnumerable)--elements being ints in this case--which the compiler infers. The name of the function argument is left of the =>
the function body is right of the =>. (Read => as "this is a function where the argument item goes to the body right of the => ") The body is an expression that evaulates to a Boolean true or a false, so the return value of the function is a Boolean.
So, essentially item => item <= 29 is the same as declaring a function like the below, but it's much more concise and can be easily used as an argument to another function. Here's the long way of declaring such a function, so you can see that the lambda way of writing it is much more concise:
Boolean int func(int x)
{
if (x<=29) {
return true;
} else {
return false;
}
}
the Where or Array.FindAll functions call the lambda function on each element in the Array or IEnumerable and return (yield) back only those items where the lambda function returns true.
Update
Looks like you edited the original question to remove a reference to finding indexes, so the below is no longer relevant (the above stuff finds values of elements, not indexes of elements). But the below shows how to find both values and indexes of the array elements that satisfy the condition:
You mentioned indexes. This version also finds the indexes of the original array (not just the elements) that satisfy the criterion:
List<int> indexesInvolved = new List<int>();
var resultArray = cost.Where((item, index) =>
{
if (item <= 29) {
indexesInvolved.Add(index);
return true;
}
else {
return false;
}
}
).ToArray();
var foundIndexArray = indexesInvolved.ToArray();

How to extract (in C#) a specific attribute from every element of a List, and get a new List of these attributes?

We begin with a List<X>. Every object of X has an attribute x of type Y. Could you propose an elegant way to construct a List which is composed of the Z.x for every element Z of some List<X>?
I'm sure "manual" iteration over List<X> isn't necessary. Thanks for any advice.
If this is List<T>, then:
var newList = oldList.ConvertAll(item => item.x);
or with LINQ:
var newList = oldList.Select(item => item.x).ToList();
Note that in C# 2.0 the first version might need the generic type mentioned explicitly:
List<Y> newList = oldList.ConvertAll<Y>(delegate (X item) { return item.x; });
(but that is actually 100% identical to the first line)
There is also a static Array.ConvertAll which behaves similarly, but for arrays.

Categories