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.
Related
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
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Consider I've an array of integers {1,2,3,4,5,6,7,8} and I want to pair them up as {{1,2},{3,4} and so on} and perform subtraction on the pair and finally sum the results.
Following is the code I've now and for better understanding:
static void Main(string[] args)
{
int[] ints = { 4, 8, 8, 3, 9, 0, 7, 8, 2, 2 };
ints = ints.OrderBy(x => x).Select(x=>x).ToArray();
List<int> lints = new List<int>();
for (int i = 0, j = 1; i < ints.Length; i = i + 2, j = j + 2)
{
lints.Add(ints.ElementAtOrDefault(j) - ints.ElementAtOrDefault(i));
}
int lintsum = lints.Sum();
Console.WriteLine(lintsum);
}
Is there a better way to do this in linq in C#? And how can I do the same in python?
You can use MoreLINQ which has a Pairwise extension method on IEnumerable<T> which does exactly what you want, it invokes a delegate on an element and its predecessor:
var ints = new[] { 1, 2, 3, 4, 5 };
var result = ints.Pairwise((first, second) => second - first);
Console.WriteLine(result.Sum());
You could achieve the result using Python in the following way:
In [25]: start = [1,2,3,4,5,6,7,8]
In [26]: tuples = [item for item in zip(start[::2], start[1::2])]
In [27]: tuples
Out[27]: [(1, 2), (3, 4), (5, 6), (7, 8)]
In [28]: answer = sum(rhs-lhs for (lhs, rhs) in tuples)
In [29]: answer
Out[29]: 4
An alternative solution using Python is:
ints = [1, 2, 3, 4, 5, 6, 7, 8]
print sum(y - x for x, y in zip(*([iter(ints)] * 2)))
ints = [4, 8, 8, 3, 9, 0, 7, 8, 2, 2]
print sum(y - x for x, y in zip(*([iter(ints)] * 2)))
Giving:
4
-9
When using large arrays of number, it might be preferable to use numpy:
import numpy as np
ints = np.array([1, 2, 3, 4, 5, 6, 7, 8])
tuples = ints.reshape(-1,2))
Then take the difference and sum
(tuples[:,1]-tuples[:,0]).sum()
Or alternatively
np.diff(tuples).sum()
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
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 8 years ago.
Improve this question
This is my code i can able to get first five integer and i can skip first three integer
i need to skip a single number from this array .
how may i achieve with this code?
class Program
{
static void Main(string[] args)
{
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var result1 = ints.Take(5);
var result2 = ints.Skip(3);
Array.ForEach(result1.ToArray(), n => Console.WriteLine(n));
Console.ReadLine();
Array.ForEach(result2.ToArray(), n => Console.WriteLine(n));
Console.ReadLine();
}
}
Clarification: i need to skip ints[4], so i want only 1, 2, 3, 4, 6, 7, 8, 9, 10.
You can use Enumerable.Where.
If you want to skip a specific index you can use the overload of Where:
var result = ints.Where((i, index) => index != 4);
If you instead want to skip all 3 in the array:
var result = ints.Where(i => i != 3);
To add to the existing answers, this will allow you to skip a particular position in the array.
List<int> output = new List<int>();
int skipIteration = 3;
for (int x = 0; x < ints.Length; x++)
{
if (x != skipIteration)
{
output.Add(ints[x]);
}
}
ints = output.ToArray();
this is the "quick" way without accounting for performance/reducing allocation
You can filter an array using the IEnumerable.Where method.
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var numberToOmit = 5;
var filteredList = ints.Where(number => number != numberToOmit).toList();
filteredList.forEach(item => Console.WriteLine(item));
Is there a linq command that will filter out duplicates that appear in a sequence?
Example with '4':
Original { 1 2 3 4 4 4 5 6 7 4 4 4 8 9 4 4 4 }
Filtered { 1 2 3 4 5 6 7 4 8 9 4 }
Thanks.
Not really. I'd write this:
public static IEnumerable<T> RemoveDuplicates(this IEnumerable<T> sequence)
{
bool init = false;
T current = default(T);
foreach (var x in sequence)
{
if (!init || !object.Equals(current, x))
yield return x;
current = x;
init = true;
}
}
Yes there is! One-line code and one loop of the array.
int[] source = new int[] { 1, 2, 3, 4, 4, 4, 5, 6, 7, 4, 4, 4, 8, 9, 4, 4, 4 };
var result = source.Where((item, index) => index + 1 == source.Length
|| item != source[index + 1]);
And according to #Hogan's advice, it can be better:
var result = source.Where((item, index) => index == 0
|| item != source[index - 1]);
More readable now i think. It means "choose the first element, and those which isn't equal to the previous one".
Similar to svick's answer, except with side effects to avoid the cons and reverse:
int[] source = new int[] { 1, 2, 3, 4, 4, 4, 5, 6, 7, 4, 4, 4, 8, 9, 4, 4, 4 };
List<int> result = new List<int> { source.First() };
source.Aggregate((acc, c) =>
{
if (acc != c)
result.Add(c);
return c;
});
Edit: No longer needs the source.First() as per mquander's concern:
int[] source = new int[] { 1, 2, 3, 4, 4, 4, 5, 6, 7, 4, 4, 4, 8, 9, 4, 4, 4 };
List<int> result = new List<int>();
result.Add(
source.Aggregate((acc, c) =>
{
if (acc != c)
result.Add(acc);
return c;
})
);
I think I still like Danny's solution the most.
You can use Aggregate() (although I'm not sure whether it's better than the non-LINQ solution):
var ints = new[] { 1, 2, 3, 4, 4, 4, 5, 6, 7, 4, 4, 4, 8, 9, 4, 4, 4 };
var result = ints.Aggregate(
Enumerable.Empty<int>(),
(list, i) =>
list.Any() && list.First() == i
? list
: new[] { i }.Concat(list)).Reverse();
I think it's O(n), but I'm not completely sure.
If you're using .NET 4 then you can do this using the built-in Zip method, although I'd probably prefer to use a custom extension method like the one shown in mquander's answer.
// replace "new int[1]" below with "new T[1]" depending on the type of element
var filtered = original.Zip(new int[1].Concat(original),
(l, r) => new { L = l, R = r })
.Where((x, i) => (i == 0) || !object.Equals(x.L, x.R))
.Select(x => x.L);