Performing Actions With Pairs in Arrays/Lists in C# - c#

Sorry if the title's worded a bit weird but this is what I'm trying to get to.
Lets say you have an array of integers like this:
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
What would be the best way to use this array to return a new array but with the values of each pair summed together, so using the array above, it would return
{ 3, 7, 11, 15, 19 }
Obviously you can so something basic like
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var x = new List<int>();
for (int i=0;i<arr.Length;i+=2)
x.Add(arr[i] + arr[i+1]);
But if you want to keep your code concise and/or work with different items, this doesn't really seem like the best option.
So is there any other/better way to do this? I was testing some ideas with Enumerable.Aggregate but couldn't come up with anything, please share ideas.

I would argue that your approach is perfectly fine, but for LINQ you can do some stuff with Chunk:
var x = arr
.Chunk(2)
.Where(c => c.Length == 2)
.Select(c => c.Sum())
.ToArray();

Well, your code is readable and efficien; however, you can generalize your current solution a bit:
Last array item(s) can well have no pair
We can combine not only pairs, but three or four items etc.
If you are looking for such kind of code for
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
the modifiction of your solution can be:
const int size = 2;
int[] result = new int[arr.Length / size + Math.Sign(arr.Length % size)];
for (int i = 0; i < arr.Length; ++i)
result[i / size] += arr[i];
For instance, if we set size = 3; then for we'll get { 6, 15, 24, 10 } as the result. Note, that the last group is incomplete:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
| | | | | | ||
6 15 24 10

Related

C# Integer list solution [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have list
List<int> listnumbers
with values { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }.
In some cases i need to add new value for existing values in list example , 0 => 5, 1 => 6 ....
Is there way to do that?
EDIT
i want number to
number 0 have stake 5
number 1 have stake 6
But i cannot that declare on begining of program , only in some cases i woud join stakes
EDIT 2
I will use multidimensional array so it will be
0=>5
1=>6
array[0][0] = 0;
array[0][1] = 5;
array[1][0] = 1;
array[1][1] = 6;
Perhaps this could do what you're looking for. You need some kind of data structure to store the additional information:
public class NumberLink {
int Value { get; set; }
int Link { get; set; }
}
List<NumberLink> numberLinks =
new List<int> {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
}
.Select(i => new NumberLink { Value = i })
.ToList();
numberLinks.First(nl => nl.Value == 0).Link = 5;
numberLinks.First(nl => nl.Value == 1).Link = 6
Please note that if you will always have a range of numbers from 0..n, you don't need this. You can simply use the position of the item in the list to represent the first value, such that a list { 5, 6 } indicates that 0 goes to 5 and 1 goes to 6.
If you need to substitute a value for another, you could use Linq, something along the lines of:
List<int> list = new List<int>(){0,1,2,3,4,5,6};
var fromValue = 0;
var toValue = 7;
list = list.Select( x => x = (x == fromValue ? toValue : x)).ToList();
//- list = {7,1,2,3,4,5,6}
Here the Select statement will mutate your existing list and return a modified list of integers where every value that's equal to fromValue will be replaced with toValue
CASE 1. To add them at the end of the list:
listnumbers.Add(5);
listnumbers.Add(6);
list will be listnumbers ==> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 6 }
CASE 2. To insert them at a specific position:
listnumbers.Insert(0, 5);
listnumbers.Insert(0, 6);
list will be listnumbers ==> { 6, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
CASE 3. To insert them at position that maintains an ordered list (min to max):
listnumbers.Insert(listnumbers.FindIndex(0, x => x == 5) + 1, 5);
listnumbers.Insert(listnumbers.FindIndex(0, x => x == 6) + 1, 6);
list will be listnumbers ==> { 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12 } and in this case, I am using predicates within FindIndex method.
I am guessing that you want to add some constant value to each element of a list and return it as a new list.
List<int> answer = listnumbers.Select(x => x+valueToBeAdded).ToList();
The above statement adds a constant to all elements of the list and returns it as a new list.

Sort jagged array by second column using insertion sort C#

I have a jagged array in a c# program that is declared where column one represents a year, column two represents the number of a month (1-12) and column three represents some data for that month:
double[][] data = new double[3][]
{
new double[] {1930,1931,1931,1931,1931,1931,1931,1931,1931,1931,1931,1931,1931,1932,1932,1932,1932,1932,1932,1932,1932,1932,1932,1932,1932},
new double[] {12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
new double[] {5, 6, 8, 3, 5, 8, 9, 6, 5, 6, 7, 5, 3, 2, 2, 2, 5, 7, 8, 3, 2, 2, 1, 2, 5}
};
As you can see, the first array is ordered. I would like to know how I could sort the jagged array by the second column , in ascending order like this.
{1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1931,1932,1930,1931,1932}
{1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12}
etc...
My question is, how would I be able to implement this using an insertion sort. It needs to be a custom algorithm and cannot make use of the Array.Sort algorithm that comes as part of C#
Thanks
The insertion sort algorithm can easily be generalized (abstracted) to work on indexes by defining two functions - one to compare two indexes and one to swap two indexes, like this:
public static class Algorithms
{
public static void InsertionSort(int start, int count, Func<int, int, int> compare, Action<int, int> swap)
{
for (int i = start + 1, end = start + count; i < end; i++)
for (int j = i; j > start && compare(j - 1, j) > 0; j--)
swap(j - 1, j);
}
}
Now you can achieve your goal by comparing second columns and swap all columns like this:
Algorithms.InsertionSort(0, data[1].Length,
(a, b) => data[1][a].CompareTo(data[1][b]),
(a, b) => { foreach (var col in data) Algorithms.Swap(ref col[a], ref col[b]); });
where Algorithms.Swap is another little helper:
public static void Swap<T>(ref T a, ref T b) { T c = a; a = b; b = c; }

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 split array in two arrays?

I have one array and want split it in to two:
Now: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
New_1: [0, 2, 4, 6, 8]
New_2: [1, 3, 5, 7, 9]
So take the one element and skip the next element.
Look easy but how can i do it with C#?
Thanks a lot
You can use linq, Enumerable.Where and get the array with elements that have even and odd indexes.
var New_1 = arr.Where((c,i) => i % 2 == 0).ToArray();
var New_2 = arr.Where((c,i) => i % 2 != 0).ToArray();
You can get the index of element of collection and apply condition to check if index is even or odd and get the arrays according.
Enumerable.Where Method (IEnumerable, Func) filters a sequence of values based on a predicate.
Each element's index is used in the logic of the predicate function.
The first argument of predicate represents the element to test. The
second argument represents the zero-based index of the element within
source, msdn
How about something like
int[] arr = new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] arr1 = arr.Where((x, i) => i % 2 == 0).ToArray();
int[] arr2 = arr.Where((x, i) => i % 2 == 1).ToArray();
int[] arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int i = 0;
List<int[]> twoArr = arr.GroupBy(x => i++ % 2).Select(g => g.ToArray()).ToList();

Finding a sequence in a List

I have a list of integers that I would like to search for a sequence.
For example, if I have a master list:
1, 2, 3, 4, 9, 2, 39, 482, 19283, 19, 23, 1, 29
And I want to find sequence:
1, 2, 3, 4
I would like some easy way to fill a subset list with:
1, 2, 3, 4 + the next five integers in the master list
And then remove the integers in the subset list from the master list so at the end of the operation, my lists would look like this:
Master list:
19, 23, 1, 29
Subset list:
1, 2, 3, 4, 9, 2, 39, 482, 19283
Hope that makes sense. I'm guessing maybe LINQ would be good for something like this, but I've never used it before. Can anyone help?
You could start with writing a function IndexOfSublist that can find a sublist inside a list. This has been asked many times before.
Assuming you have implemented IndexOfSublist, use it to find the first element of your result, then you could use GetRange to select the elements that you want to keep and then RemoveRange to remove the elements from the original list.
List<int> l = new List<int> { 1, 1, 2, 3, 4, 9, 2, 39, 482, 19283, 19, 23, 1, 29 };
List<int> needle = new List<int> { 1, 2, 3, 4 };
int i = indexOfSubList(l, needle);
if (i != -1)
{
// TODO: What should we do if there are fewer than four
// elements left after the needle? Currently we just throw.
List<int> result = l.GetRange(i, needle.Count + 4);
l.RemoveRange(i, result.Count);
// TODO: Do something with the result;
}
HINT
you can try something like this along with an iterator:
List<int> n = new List<int>() { 1, 2, 3, 4, 9, 2, 39, 482, 19283, 19, 23, 1, 29 };
List<int> toFind = new List<int>() { 1, 2, 3, 4 };
if (n.Skip(indextostart).Take(4).ToList()==toFind)
{
n.RemoveRange(indextostart,4);
}

Categories

Resources