Arrange Array in C# Issue - c#

I've an array sequence 20,40,60,10,30,50. I want to sort this sequence into the following order 60,40,50,20,30,10 in C#.
Any Help? Thanks in advance☺

Very Simple if you have an Array
int[] arr = { 1, 2, 3, 5, 9, 0, 2, 10 };
arr.OrderBy(a => a);
arr.Reverse();
in case of list
List<int> abc = new List<int> { 1, 2, 3, 5, 9, 0, 2, 10 };
abc.Sort();
abc.Reverse();

Just use OrderByDescending of LINQ:
var list = new[] {20, 40, 60, 10, 30, 50};
var newList = list.OrderByDescending(x => x);
Console.WriteLine(string.Join(",", newList)); //60,50,40,30,20,10

You can try this
int[] array = new int[] { 20, 40, 60, 10, 30, 50 };
Array.Sort<int>(array,
new Comparison<int>((element1, element2) => element1.CompareTo(element2)));
to reverse sort
element2.CompareTo(element1)

Related

Get array items by index

I have two arrays, one with values an one with indices
int[] items = { 1, 2, 3, 7, 8, 9, 13, 16, 19, 23, 25, 26, 29, 31, 35, 36, 39, 45 };
int[] indices = { 1, 3, 5, 6, 7, 9 };
now I want a result array from the items selected by the indices of indices array
// 2, 7, 9, 13, 19
int[] result = new []{ items[1], items[3], items[5], items[6], items[7], items[9] };
Question: Is there a more generic approach for this?
var results = Array.ConvertAll(indices, i => items[i]);
Try using Linq:
int[] items = { 1, 2, 3, 7, 8, 9, 13, 16, 19, 23, 25, 26, 29, 31, 35, 36, 39, 45 };
int[] indices = { 1, 3, 5, 6, 7, 9 };
int[] result = indices
.Select(index => items[index])
.ToArray();
A good old for loop should be able to do this job as well:
int[] items = { 1, 2, 3, 7, 8, 9, 13, 16, 19, 23, 25, 26, 29, 31, 35, 36, 39, 45 };
int[] indices = { 1, 3, 5, 6, 7, 9 };
List<int> resultList = new List<int>();
for (int i = 0; i < indices.Length; i++)
{
resultList .Add(items[indices[i]]);
}
Explanation:
when using the [ ] operator to access a specific index in indices it will return the number. This can again be used to index/access a specific location in items. So you have a double indexing.
EDIT:
If you need the result as an array you can use the ToArray method to convert it:
int [] result = resultList.ToArray();
For the sake of alternative:
int[] result = items.Select((value, index) => new { Index = index, Value = value }) //Add indexes
.Where(w => indices.Contains(w.Index)) //Filter by indexes
.Select(s => s.Value).ToArray(); //Extract values to result array

Build pairs out of list - without repetition

to do it in linqI have an integer List and want to group these to a list of integer pairs.
var input = new[] {1, 24, 3, 2, 26, 11, 18, 13};
result should be: {{1, 24}, {3, 2}, {26, 11}, {18, 13}}
I tried:
List<int> src = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
var agr = src.Select((n, i) => new Tuple<int, int>(i++ % 2, n))
.GroupBy(t => t.Item1)
.ToList();
var wanted = agr[0].Zip(agr[1], (d, s) => new Tuple<int, int>(d.Item2, s.Item2));
Is there a better way to do it in linq?
Of course I can do it with a simple for-loop.
Edit:
I think I give MoreLinq a try. I also mark this as the answer even if it's an extension and not pure linq.
By the way - I think doing it with a for-loop is much more understandable.
You can use MoreLINQ Batch to split your input into a list of "length 2" lists. Or any other length you want.
List<int> src = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
List<IEnumerable<int>> wanted = src.Batch(2).ToList();
No need for MoreLINQ; Enumerate even- and odd-indexed values, and Zip
int[] input = new int[8] { 1, 24, 3, 2, 26, 11, 18, 13 };
var evenPositioned = input.Where((o, i) => i % 2 == 0);
var oddPositioned = input.Where((o, i) => i % 2 != 0);
var wanted = evenPositioned.Zip(oddPositioned, (even, odd) => new { even, odd }).ToList();
If you can garantee, that the length of the source can always be devided by 2:
List<int> src = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
var Tuple<int, int>[] wanted = new Tuple<int, int>[src.Count /2];
for(var i = 0; i < src.Count; i = i + 2)
wanted[i/2] = new Tuple<int, int>(src[i], src[i+1]);
a simple for loop is enough for this.Just start with 1 and increment it by 2
List<int> src = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
var list = new List<Tuple<int, int>>();
for(int i =1;i<src.Count;i=i+2)
{
list.Add(new Tuple<int, int>(src[i-1],src[i]));
}
In case of odd count last item will be skipped
Another simple loop solution featuring C# 7 tuples.
var input = new List<int> { 1, 24, 3, 2, 26, 11, 18, 13 };
var wanted = new List<(int, int)>();
for (var index = 0; index < input.Count; index += 2) {
wanted.Add((input[index], input[index + 1]));
}

How to find first specific item and then take 3 following?

I am trying to find position in a List based on where LINQ statement and get that item and next (x) amount. Example code:
List<int> numbers = new List<int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
numbers = numbers.Where(elt => elt == 6).Take(3).ToList();
I am trying to get back a filtered list of 6,7,8. However this is not working. Am I approaching this wrong?
Thanks in advance!
You almost got it. You just need to change the Where to a SkipWhile:
numbers = numbers.SkipWhile(elt => elt != 6).Take(3).ToList();
You have to use Where() overload that takes index of item as well and then use with indexOf():
List<int> numbers = new List<int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
var result = numbers.Where((x, i) => i >= numbers.IndexOf(6)).Take(3);
Here's another approach which comes into play when it's possible that the number is not unique and you want all occurences including the two next followers:
List<int> numbers = new List<int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 6, 7, 8, 9, 6 });
numbers = Enumerable.Range(0, numbers.Count)
.Where(index => numbers[index] == 6)
.SelectMany(index => numbers.Skip(index).Take(3))
.ToList(); // 6,7,8,6,7,8,6

How to group the same values in a sequence with LINQ?

I have a sequence. For example:
new [] { 10, 1, 1, 5, 25, 45, 45, 45, 40, 100, 1, 1, 2, 2, 3 }
Now I have to remove duplicated values without changing the overall order. For the sequence above:
new [] { 10, 1, 5, 25, 45, 40, 100, 1, 2, 3 }
How to do this with LINQ?
var list = new List<int> { 10, 1, 1, 5, 25, 45, 45, 45, 40, 100, 1, 1, 2, 2, 3 };
List<int> result = list.Where((x, index) =>
{
return index == 0 || x != list.ElementAt(index - 1) ? true : false;
}).ToList();
This returns what you want. Hope it helped.
var list = new List<int> { 10, 1, 1, 5, 25, 45, 45, 45, 40, 100, 1, 1, 2, 2, 3 };
var result = list.Where((item, index) => index == 0 || list[index - 1] != item);
It may be technically possible (though I don't think you can with a one-liner) to solve this with LINQ, but I think it's more elegant to write it yourself.
public static class ExtensionMethods
{
public static IEnumerable<T> PackGroups<T>(this IEnumerable<T> e)
{
T lastItem = default(T);
bool first = true;
foreach(T item in e)
{
if (!first && EqualityComparer<T>.Default.Equals(item, lastItem))
continue;
first = false;
yield return item;
lastItem = item;
}
}
}
You can use it like this:
int[] packed = myArray.PackGroups().ToArray();
It's unclear from the question what should be returned in the case of 1,1,2,3,3,1. Most answers given return 1,2,3, whereas mine returns 1,2,3,1.
You can use Contains and preserve order
List<int> newList = new List<int>();
foreach (int n in numbers)
if (newList.Count == 0 || newList.Last() != n)
newList.Add(n);
var newArray = newList.ToArray();
OUTPUT:
10, 1, 5, 25, 45, 40, 100, 1, 2, 3
Did you try Distinct?
var list = new [] { 10, 20, 20, 5, 25, 45, 45, 45, 40, 100, 1, 1, 2, 2, 3 };
list = list.Distinct();
Edit: Since you apparently only want to group items with the same values when consecutive, you could use the following:
var list = new[] { 10, 1, 1, 5, 25, 45, 45, 45, 40, 100, 1, 1, 2, 2, 3 };
List<int> result = new List<int>();
foreach (int item in list)
if (result.Any() == false || result.Last() != item)
result.Add(item);

C# Creating an array of arrays

I'm trying to create an array of arrays that will be using repeated data, something like below:
int[] list1 = new int[4] { 1, 2, 3, 4 };
int[] list2 = new int[4] { 5, 6, 7, 8 };
int[] list3 = new int[4] { 1, 3, 2, 1 };
int[] list4 = new int[4] { 5, 4, 3, 2 };
int[,] lists = new int[4, 4] { list1 , list2 , list3 , list4 };
I can't get it to work and so I'm wondering if I'm approaching this wrong.
What I'm attempting to do is create some sort of method to create a long list of the values so I can process them in a specific order, repeatedly. Something like,
int[,] lists = new int[90,4] { list1, list1, list3, list1, list2, (and so on)};
for (int i = 0; i < 90; ++i) {
doStuff(lists[i]);
}
and have the arrays passed to doStuff() in order. Am I going about this entirely wrong, or am I missing something for creating the array of arrays?
What you need to do is this:
int[] list1 = new int[4] { 1, 2, 3, 4};
int[] list2 = new int[4] { 5, 6, 7, 8};
int[] list3 = new int[4] { 1, 3, 2, 1 };
int[] list4 = new int[4] { 5, 4, 3, 2 };
int[][] lists = new int[][] { list1 , list2 , list3 , list4 };
Another alternative would be to create a List<int[]> type:
List<int[]> data=new List<int[]>(){list1,list2,list3,list4};
The problem is that you are attempting to define the elements in lists to multiple lists (not multiple ints as is defined). You should be defining lists like this.
int[,] list = new int[4,4] {
{1,2,3,4},
{5,6,7,8},
{1,3,2,1},
{5,4,3,2}};
You could also do
int[] list1 = new int[4] { 1, 2, 3, 4};
int[] list2 = new int[4] { 5, 6, 7, 8};
int[] list3 = new int[4] { 1, 3, 2, 1 };
int[] list4 = new int[4] { 5, 4, 3, 2 };
int[,] lists = new int[4,4] {
{list1[0],list1[1],list1[2],list1[3]},
{list2[0],list2[1],list2[2],list2[3]},
etc...};
I think you may be looking for Jagged Arrays, which are different from multi-dimensional arrays (as you are using in your example) in C#. Converting the arrays in your declarations to jagged arrays should make it work. However, you'll still need to use two loops to iterate over all the items in the 2D jagged array.
This loops vertically but might work for you.
int rtn = 0;
foreach(int[] L in lists){
for(int i = 0; i<L.Length;i++){
rtn = L[i];
//Do something with rtn
}
}
The following will give you an array in the iterator variable of foreach
int[][] ar =
{
new []{ 50, 50, 1 },
new []{ 80, 40, 2 },
new []{ 10, 60, 3 },
new []{ 51, 38, 4 },
new []{ 48, 38, 5 }
};

Categories

Resources