how to join two Lists in linq - c#

i have two List A,B which consists integer values ,list A contains 40 to 1 list B contains 40 to 79 i like to both values except 40 and store it in another list using Linq.The resultant list like this {80,80...}. how can i do this? Is it possible to do this?

It sounds like you're trying to "join" these in a pairwise fashion by index: the first element from each list, then the second element etc. That suggests you want Zip, which was introduced in .NET 4:
var zipped = list1.Zip(list2, (x1, x2) => x1 + x2);
If you're using .NET 3.5, you can use a separate implementation of the same method, such as the one in MoreLINQ.
EDIT: Alternatively, Eric Lippert posted some source code for Zip a while ago, too.

Check out the IEnumerable<T>.Join() method.

using System;
using System.Linq;
class Program
{
static void Main()
{
// Two source arrays.
var array1 = new int[] { 1, 2, 3, 4, 5 };
var array2 = new int[] { 6, 7, 8, 9, 10 };
// Add elements at each position together.
var zip = array1.Zip(array2, (a, b) => (a + b));
// Look at results.
foreach (var value in zip)
{
Console.WriteLine(value);
}
}
}
--- Output of the program ---
7
9
11
13
15

Try Joining them together
http://weblogs.asp.net/rajbk/archive/2010/03/12/joins-in-linq-to-sql.aspx
http://msdn.microsoft.com/en-us/library/bb397676.aspx

Related

Adding two columns using Deedle in C#

Given the following CSV file
A,B
2,3
5,7
9,11
I'd like to add the two columns, resulting in
A,B,C
2,3,5
5,7,12
9,11,20
using C# and Deedle.
using Deedle;
using System.IO;
using System.Linq;
namespace NS
{
class AddTwoColumns
{
static void main(string[] args)
{
var root = "path/to";
var df = Frame.ReadCsv(Path.Combine(root, "data.csv"));
var a = df.GetColumn<int>("A");
var b = df.GetColumn<int>("B");
var c = df.Select(x => x.a + x.b);
df.AddColumn("C", c);
df.Print();
}
}
}
Neither the
reference
nor the tutorial
(series,
frame)
is particularly illuminating.
What is the correct df.Select() for this simple operation?
a and b are just Deedle.Series which you can perform numerical operations on. So, you can do this just by adding both series:
// simply add the series
var c = a + b;
df.AddColumn("C", c);
df.Print();
// output
A B C
0 -> 2 3 5
1 -> 5 7 12
2 -> 9 11 20
The Statistics and calculations section (of the page you linked to) briefly mentions arithmetic operations. It also features a note on missing data which you might need to consider:
Point-wise and scalar operators automatically propagate missing data.
When calculating s1 + s2 and one of the series does not contain data
for a key k, then the resulting series will not contain data for k.
I know this question is particularly addressed for C#, but I hope this F# approach can help somehow:
Frame.ReadCsv(#"C:\Users\flavi\Downloads\sample.txt")
|> fun frame->
Frame.addCol "C"
(Frame.mapRowValues (fun row ->
row.GetAs<int>("A") + row.GetAs<int>("B")
)frame) frame

Different kind of concatenate two arrays in c#

I have two lists posted from view to controller such as
int[] blablaIds = { 13, 377, 1002 };
int[] secondBlaBlaIds = { 7, 18, 126 };
For some reason I want to explicitly combine these as
int[] combinedIds = { { 7, 13 }, {18, 377}, {126, 1002} }
Is it possible with LINQ?
There's no such thing as a list of long or int you're going to have to pick one and then convert the other list to the correct datatype. Once they're the same datatype you can easily concat the two lists.
longIds.Concat(intIds.Cast<long>());
As Jon Skeet has identified in the comments your question is incredibly difficult to answer in its current form. If you're looking to create a paired list of items from the first and second you could try using .Zip. You're still going to have to do some casting if you want ints and longs to coexist in the same collection. Here's an example (not verified with IDE).
var zipped = firstIds.Zip(secondIds, (first, second) => new List<long> {first, (long) second});
Have a look at SelectMany. It's rather powerful and should provide the functionality you are looking for.

Create a list from a static method result

I have the following snippet of code bellow. I would like to display the result of the new list once FindEvenNumber(numbers) is called in the Main().
Not sure how to do this..
static void Main(string[] args)
{
List<int> numbers = new List<int>() { 2, 3, 4, 10, 12, 34 };
//You can just call a static method you don't have to instantiate.
FindEvenNumber(numbers);
}
public static List<int> FindEvenNumber(List<int> evenNumbers)
{
List<int> evenNumbersNew = new List<int>();
foreach (int ij in evenNumbers)
{
if (ij % 2 == 0)
evenNumbersNew.Add(ij);
}
return evenNumbersNew;
}
You can loop your list, but I would use a one-liner
Console.WriteLine(string.Join(",", FindEvenNumber(numbers)));
You can even emded FindEvenNumber into this one-liner using Linq.
Console.WriteLine(string.Join(",", numbers.Where(i => i % 2 == 0)));
In the main, you can replace the line
FindEvenNumber(numbers);
with
System.Console.WriteLine(String.Join(", ", FindEvenNumber(numbers)));
In addition, if you don't need a List, I'd suggest to change your method to:
public static IEnumerable<int> FindEvenNumber(List<int> evenNumbers)
{
foreach (int ij in evenNumbers)
{
if (ij % 2 == 0)
yield return ij;
}
}
where the keyword yield does the job for you.
Another suggestion is to use HashSet instead of List if you want the numbers to be unique.
The other answers provided seem to be assuming the O.P. has full knowledge of string.Join and even LINQ. I'm providing this answer as the O.P. may not understand those concepts, yet.
The question restated is:
How do I get the results of a method and then use those results?
Let's break down the Main method:
static void Main(string[] args)
{
// a new List has bee created with a set of integers
List<int> numbers = new List<int>() { 2, 3, 4, 10, 12, 34 };
// the numbers List is now being provided to the FindEvenNumber method,
// but the results of the method are not used.
FindEvenNumber(numbers);
// To store the results of FindEvenNumber:
List<int> evenNumbers = FindEvenNumber(numbers);
// To use the results, loop over each item:
foreach(int i in evenNumbers)
{
Console.WriteLine(i);
}
}
A couple of notes:
The original numbers List is never modified, it is simply given to FindEvenNumber which returns a new List.
There is no need to call .ToString() against the integer due to Console.WriteLine doing that for you.
Using string.Join
We can take this a bit further if the goal is to:
print out everything returned from FindEvenNumber
use a comma to separate the numbers being printed.
Instead of using a foreach loop and calling Console.WriteLine inside the loop, we can use the .NET string.Join method to Join the contents of a collection into a single string:
// To store the results of FindEvenNumber:
List<int> evenNumbers = FindEvenNumber(numbers);
// store the results of string.Join into a local variable:
string myNumbers = string.Join(",", evenNumbers);
// print the string to the Console:
Console.WriteLine(myNumbers);
Using LINQ
An alternative to using the static method of FindEvenNumber, we can take advantage of LINQ to project the original list into a new list while invoking an anonymous method within the LINQ statement:
IEnumerable<int> evenNumbers = numbers.Where(x => x % 2 == 0);
All we've done in the above is take the logic from FindEvenNumber and move it into a LINQ expression that says:
For Each integer in the numbers list (represented by x), find the
numbers that are divisible by 2 with a remainder of 0.
In the original FindEvenNumber, the logic was: ij % 2 == 0; the logic is exactly the same in the LINQ version, but ij is now represented by x in the LINQ version.
Briging all concepts together
Now that everything has been explained, the concepts can be brought together:
static void Main(string[] args)
{
// a new List has bee created with a set of integers
List<int> numbers = new List<int>() { 2, 3, 4, 10, 12, 34 };
// store the results of string.Join into a local variable:
string myNumbers = string.Join(",", numbers.Where(x => x % 2 == 0));
// print the string to the Console:
Console.WriteLine(myNumbers);
}
And if you wanted to be even more compact:
static void Main(string[] args)
{
// a new List has bee created with a set of integers
List<int> numbers = new List<int>() { 2, 3, 4, 10, 12, 34 };
// print the string to the Console:
Console.WriteLine(string.Join(",", numbers.Where(x => x % 2 == 0)));
}

Contain a number just once in an array

How do I make an array contain a number just once?From any random numbers added to a textbox i need to first convert them to ints then with the separator i make the program understand the separate ints but how do I an int to be counted in the result list of ints just once?
You could start with using a HashSet as the collection type (.Net 3.5 and higher). This will disallow duplicate values. Then, if you can't use the HashSet as is, you can call .ToArray on it.
That is:
HashSet<int>
You can use Distinct method
input.Split(new char[]{separator},StringSplitOptions.RemoveEmptyEntries)
.Select(x=>int.Parse(x))
.Distinct();
If you want to avoid LINQ
var array=input.Split(new char[]{separator},StringSplitOptions.RemoveEmptyEntries);
var set=new HashSet<int>();
foreach(var x in array)set.Add(int.Parse(x));
var unique=set.ToArray();
Use LINQ's Distinct method to remove the duplicates:
var numbers = new[] { 1, 2, 2, 3 };
numbers = numbers.Distinct().ToArray(); // 1, 2, 3
You can use Array.Contains to check if an item already exists in an array. I'd suggest using a generic collection such as a List or Dictionary instead, though.
Check LINQ method Distinct
Example use:
List<int> ages = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 };
IEnumerable<int> distinctAges = ages.Distinct();
Console.WriteLine("Distinct ages:");
foreach (int age in distinctAges)
{
Console.WriteLine(age);
}
/*
This code produces the following output:
Distinct ages:
21
46
55
17
*/

Binary Search on the first element in a multiple dimensional array

My goal is to perform a binary search for only the first element in a 2D array. I have been searching all day to find if it is possible using BinarySearch() in .NET but I can't find a thing.
To make this clearer. Imagine I had a 1D array, unsorted. If I sort the array, I lose the original index. I would like to create a second element of my array to hold the original index (this I can do) then sort by first element, then binary search over the first elements.
If anyone could push me in the right direction I'd be very grateful.
Thanks
Well, if I understand you correctly, you need something like this:
// initialize the array and the indexes array
var a2D = new int[2][];
a2D[0] = new[] { 3, 14, 15, 92, 65, 35 }; // <-- your array (fake data here)
a2D[1] = Enumerable.Range(0, a2D[0].Length).ToArray(); // create the indexes row
// sort the first row and the second one containing the indexes
Array.Sort(a2D[0], a2D[1]);
// now a2D array contains:
// row 0: 3, 14, 15, 35, 65, 92
// row 1: 0, 1, 2, 5, 4, 3
// and you can perform binary search on the first row:
int columnIndexOf35 = Array.BinarySearch(a2D[0], 35);
// columnIndexOf35 = 3
//
// a2D[0][columnIndexOf35] = 35 <- value
// a2D[1][columnIndexOf35] = 5 <- original index
As per MSDN, Array.BinarySearch method operates only with one-dimensional arrays, so it is impossible to use it directly in your case. Some of the options you have are:
Extract first column into a separate array and call Array.BinarySearch on it.
Define custom class Pair that implements interface IComparable and construct your array with the instances of this class.
Implement binary search on two dimensional array by yourself.
It looks like you want to have object that holds data and "original index" and than sort/search array of objects by data.
(This answer shows Andrei's option 2)
class IndexedData:IComparable
{
public MyType Data;
public int OriginalIndex;
public int CompareTo(object obj) {
// add correct checks for null,.. here
// and return correct comparison result.
// I.e. if MyType is IComparable - just delegate.
return Data.CompareTo(obj);
}
Check IComparable on MSDN for implementation/usage details.
Depending on what you're planning to do with the arrays afterwards, another solution might be to use LINQ.
var unsortedStartingArray = new[] {3, 6, 2, 1, 20, 20};
var q = unsortedStartingArray
.Select((item, index) => new {item, index})
.ToLookup(x => x.item, x => x.index);
var notFound = q[30]; // An empty array. Nothing found
var indexOf1 = q[1].First(); // returns 3
var multipleIndexsOf20 = q[20]; // Returns an array with 4, 5
The index into the lookup would then be the value you're searching for. Performance wise I would guesstimate this to be faster aswell about 5 times slower from my crude testing.

Categories

Resources