Descarte's sqaure of array [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
How I can get ordered pairs of elements from some array, using LINQ? For example,
I have:
int[] d = { 1, 2, 3 };
I need:
{ {1, 1}, {1, 2}, ...., {3, 3} }
I tried that LINQ query, but it returns
{ {1, 1}, {2, 2}, {3, 3}, {1, 1}, {2, 2}, {3, 3}, {1, 1}, {2, 2}, {3,
3} }
var pairs = d.SelectMany(a => d.Select(b => new[] { a, b }));
Please, help me to find my error.

Like this:
var result = d.SelectMany(a => d, Tuple.Create)
.Where(c=> c.Item1 <= c.Item2).ToArray();

this code work
int[] d = { 1, 2, 3 };
var query = (from elem1 in d
from elem2 in d
where elem1>= elem2
select elem1< elem2? new List<int>() { elem1, elem2 }: new List<int>() { elem2, elem1 }
).Distinct().ToArray();

Related

Get first element in each row of 2d array

How do you iterate through a 2d array and get the first element in each row? For example:
int[,] array = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} };
desired output: 1 4 7 10
Something like this should do the trick:
int[,] array = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} };
for (int row = 0; row < array.GetLength(0); ++row)
{
Console.WriteLine(array[row, 0]);
}
Try it online

C# List of List initialization, { new List<int>() {1,2,3} } not working? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I am trying to create a List of List of Integers, and I wanted to do it "inline" without using .Add, but it doesnt work, why?
// This is working
List<List<int>> lists = new List<List<int>>();
lists.Add(new List<int>() { 1, 2, 3 });
lists.Add(new List<int>() { 4, 5, 6 });
lists.Add(new List<int>() { 7, 8, 9 });
// This compiles, no red, but is not working, the list stays empty
List<List<int>> secondList = new List<List<int>>();
{
new List<int>() { 1, 2, 3 };
new List<int>() { 4, 5, 6 };
new List<int>() { 7, 8, 9 };
};
Also, why the second example needs ; between the lists and not just "," like with a list of some type?
P.S. Solved I just realized that I had another issue, I wrote it as List<List<int>> list = new List<List<int>>(); { ... }; in my code and that first semicolon shouldnt be there, a simple typo :D and it was asking for ; on the lines and was giving me errors when I was using ,
Solution:
List<List<int>> secondList = new List<List<int>>
{
new List<int>() { 1, 2, 3 },
new List<int>() { 4, 5, 6 },
new List<int>() { 7, 8, 9 }
};
The second example has incorrect syntax. You should use comma as separator, not ;.
var lists = new List<List<int>>
{
new List<int> { 1, 2, 3 },
new List<int> { 4, 5, 6 },
new List<int> { 7, 8, 9 }
};
This works fine.
The second example does not compile, and should instead look like this:
List<List<int>> lists = new List<List<int>>()
{
new List<int>() { 1, 2, 3 },
new List<int>() { 4, 5, 6 },
new List<int>() { 7, 8, 9 }
};

Find common items in multiple lists in C# linq

I searched, but I found only answers which related to two lists. But what about when they are more than two?
List 1 = 1,2,3,4,5
List 2 = 6,7,8,9,1
List 3 = 3,6,9,2,0,1
List 4 = 1,2,9,0,5
List 5 = 1,7,8,6,5,4
List 6 = 1
List 7 =
How to get the common items? as you can see one of them is empty, so the common will be empty, but I need to skip empty lists.
var data = new List<List<int>> {
new List<int> {1, 2, 3, 4, 5},
new List<int> {6, 7, 2, 8, 9, 1},
new List<int> {3, 6, 9, 2, 0, 1},
new List<int> {1, 2, 9, 0, 5},
new List<int> {1, 7, 8, 6, 2, 5, 4},
new List<int> {1, 7, 2}
};
List<int> res = data
.Aggregate<IEnumerable<int>>((a, b) => a.Intersect(b))
.ToList();
The type of Aggregate is explicitly given, otherwise aggregation of two Lists would have to be List too. It can be easily adapted to run in parallel:
List<int> res = data
.AsParallel<IEnumerable<int>>()
.Aggregate((a, b) => a.Intersect(b))
.ToList();
EDIT
Except... it does not run in parallel. The problem is operations on IEnumerable are deferred, so even if they are logically merged in parallel context, the actual merging occurs in the ToList(), which is single threaded. For parallel execution it would be better to leave IEnumerable and return to the Lists:
List<int> res = data
.AsParallel()
.Aggregate((a, b) => a.Intersect(b).ToList());
You can chain Intersect:
List<int> List1 = new List<int> {1, 2, 3, 4, 5};
List<int> List2 = new List<int> { 6, 7, 8, 9, 1 };
List<int> List3 = new List<int> { 3, 6, 9, 2, 0, 1 };
List<int> List4 = new List<int> { 1, 2, 9, 0, 5 };
List<int> List5 = new List<int> { 1, 7, 8, 6, 5, 4 };
List<int> List6 = new List<int> { 1 };
List<int> common = List1
.Intersect(List2)
.Intersect(List3)
.Intersect(List4)
.Intersect(List5)
.Intersect(List6)
.ToList();
var data = new [] {
new List<int> {1, 2, 3, 4, 5},
new List<int> {6, 7, 8, 9, 1},
new List<int> {3, 6, 9, 2, 0, 1},
new List<int> {1, 2, 9, 0, 5},
new List<int> {1, 7, 8, 6, 5, 4},
new List<int> {1},
new List<int> {},
null
};
IEnumerable<int> temp = null;
foreach (var arr in data)
if (arr != null && arr.Count != 0)
temp = temp == null ? arr : arr.Intersect(temp);
One way is to use a HashSet. You can put the items of the first collection in the hash, then iterate each collection after the first and create an new hash that you add items from the current collection to if it's in the hash. At the end you assign that common hash set to the overall one and break if it's every empty. At the end you just return the overall hash set.
public IEnumerable<T> CommonItems<T>(IEnumerable<IEnumerable<T>> collections)
{
if(collections == null)
throw new ArgumentNullException(nameof(collections));
using(var enumerator = collections.GetEnumerator())
{
if(!enumerator.MoveNext())
return Enumerable<T>.Empty();
var overall = new HashSet<T>(enumerator.Current);
while(enumerator.MoveNext())
{
var common = new HashSet<T>();
foreach(var item in enumerator.Current)
{
if(hash.Contains(item))
common.Add(item);
}
overall = common;
if(overall.Count == 0)
break;
}
return overall;
}
}

Sort 2D array based on user provided indices

In python there is a functionality (numpy.take) to sort arrays within an array, for example if I have an array (3x3):
a = [[1, 2, 3],[7,9,10],[3, 5,6]]
and I have an array of set indices
indices = [2, 0, 1]
the result shall be
array([[ 3, 5, 6], [ 1, 2, 3], [ 7, 9, 10]]).
Are there any direct approach methods/ functions as these in C# where I can pass in a jagged array and produce the same output?
Not directly, but you can achieve the same thing with Linq
var a = new[] { new[] { 1, 2, 3 }, new[] { 7, 9, 10 }, new[] { 3, 5, 6 } };
var indices = new [] { 2, 0, 1 };
var sorted = indices.Select(i => a[i]).ToArray();
foreach(var s in sorted) Console.WriteLine(string.Join(", ", s));
Note this does not check that your indices are all in range.
You can do it easily with LINQ:
var a = new[] { new[] { 1, 2, 3 }, new[] { 7, 9, 10 }, new[] { 3, 5, 6 } };
var indices = new[] { 2, 0, 1};
var result = indices
.Select(i => a[i])
.ToArray();
Or .ToList() if you prefer lists.
There is also the Array.Sort(keys, values) - MSDN
var a = new[]
{
new[] {1, 2, 3},
new[] {7, 9, 10},
new[] {3, 5, 6}
};
var indices = new[] {2, 0, 1};
var sortedArray = a.SortEx(indices);
Where SortEx is
public static class Extensions
{
public static T[][] SortEx<T>(this T[][] source, int[] indices)
{
return indices.Select(index => source[index]).ToArray();
}
}
This assumes that the all the indices in the indices array are not out of bound in a.

How to find subsets with exact length using linq lambda syntax [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Lists permutations (unknown number)
Lets say I have input of Range[1, 8]
{1,2,3,4,5,6,7,8}
and i want to find Subsets[%, {2}] (all subsets with exact length of 2)
{{1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {2, 3}, {2, 4},
{2, 5}, {2, 6}, {2, 7}, {2, 8}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8},
{4, 5}, {4, 6}, {4, 7}, {4, 8}, {5, 6}, {5, 7}, {5, 8}, {6, 7}, {6, 8}, {7, 8}}
Tried:
var values = Enumerable.Range(1, 8);
var result = from v in values
from v2 in values.Skip(v)
select new[] { v, v2 };
Here is a function to find all combinations of an input sequence of a specified size:
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> source, int n)
{
if (n == 0)
yield return Enumerable.Empty<T>();
int count = 1;
foreach (T item in source)
{
foreach (var innerSequence in source.Skip(count).Combinations(n - 1))
{
yield return new T[] { item }.Concat(innerSequence);
}
count++;
}
}
So in your case you'd use it as:
var result = Enumerable.Range(1, 8).Combinations(2);
var query = from a in Enumerable.Range(1, 8)
from b in Enumerable.Range(a + 1, 8 - a)
select String.Format("{{{0}, {1}}}", a, b);
foreach (string s in query)
{
Console.Out.WriteLine(s);
}
var lst = Enumerable.Range(1, 8);
var result = lst.Join(lst, c => 1, c => 1, (i, j) => new[] { i, j })
.Where(c => c[0] < c[1]);
Here I used the condition 1 == 1 to get the cross join of values in Enumerable.Range(1, 8) to get all possible combinations.
As noted in comments probably an easier way to generate a cross join is by:
var result = lst.SelectMany(_ => lst, (i, j) => new[] { i, j })
.Where(c => c[0] < c[1]);
but is less readable to my eyes.
Please note that this is little less efficient compared to other methods as this first gets all the possible combinations and then trim down the unwanted. Nevertheless a simple one-liner.

Categories