Contain a number just once in an array - c#

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
*/

Related

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.

Getting a continuous chain of values based on a condition in LINQ

Say I have a List of numbers:
var list = new List<int>{100, 1, 2, 4, 10, 11, 50, 54};
And I want the output to be sets of numbers that satisfy a condition of "closeness" with its adjacent values.
So for example, if I define the distance between adjacent numbers to be less than 5, I will get something like:
Set1: {100}
Set2: {1, 2, 4}
Set3: {10, 11}
Set4: {50, 54}
Since the numbers in each set are within 5 of its adjacent value.
How would I do this in LINQ? I was thinking of some combination of Aggregate() and TakeWhile() but I couldn't figure it out.
To be clear, I am looking for a generic way of solving this (i.e. an algorithm that if I change 5 to any other number would also give an output of sets that satisfy the new condition).
I'm sure there are better approaches, since you want to do it with Linq you could do something like this.
int gid=0, prevvalue = list[0];
va result = list.Select(x=>
{
var obj = Math.Abs(prevvalue-x)>=10?
new {gid= ++gid, item =x}
:new {gid= gid, item =x};
prevvalue= x;
return obj;
})
.GroupBy(x=>x.gid)
.Select(x=>x.Select(s=>s.item).ToList())
.ToArray();
Check this Demo

Split List into sublists based on border values

I would like to split up an existing sorted list into multiple sublists, based on the entries of another list.
Let's say I have an array like this:
List<int> myList = [1,3,7,23,56,58,164,185];
and another list, which defines at which places myList should be split:
List<int> borders = [4,59,170];
What's the shortest way to get a nested list where myList is split at the values defined in borders, i.e. like this:
[[1,3],[7,23,56,58],[164],[185]]
I have already solved it by manually looping through the lists, but I can imagine it's easier and shorter using Linq.
EDIT: There is one simplification: numbers can't be the same as the borders, so it's impossible that a number is contained in myList and borders at the same time.
Since you want to group the numbers into different groups, you will want to use GroupBy. The difficulty is only what you use as the key. For this, you can use the largest border value that is smaller than the number. This assumes that borders is sorted though:
List<int> myList = new List<int> { 1, 3, 7, 23, 56, 58, 164, 185 };
List<int> borders = new List<int> { 4, 59, 170 };
var groups = myList.GroupBy(i => borders.LastOrDefault(x => x < i));
foreach (var group in groups)
{
Console.WriteLine("{0}: {1}", group.Key, string.Join(", ", group));
}
This yields the following output:
0: 1, 3
4: 7, 23, 56, 58
59: 164
170: 185
Note that this is not exactly the most efficient solution as it will search for an appropriate border key for every element in myList. If your list is sorted like your example, then it’s more efficient to loop through both at the same time and just match the numbers of myList to the current or next border element. So this solution is O(n * m) while a solution O(n) is possible. On the plus side, this allows myList to be completely unsorted.
For those interested in a O(n) solution, here’s one possible take on it which is just a very general way on grouping sequences:
List<List<int>> groups = new List<List<int>>();
List<int> group = null;
int k = -1;
foreach (int num in myList)
{
if (k < 0 || num > borders[k])
{
group = new List<int>();
groups.Add(group);
k++;
}
group.Add(num);
}

Check if a single value in List in C#

How to check a single value is in a List. My List contains few random numbers: 13, 55, 34, 122, 322, 2132, 4345, 3000.
I want to have a bool check the list if it contains int 4 or any other number. List can have large numbers in three or four figures in the list.
It would be nice to guide me to design helper in webmatrix to provide bool results for this value check.
Try this,intVariable is your variable to search
bool isInList = intList.IndexOf(intVariable) != -1;
You can't get away without iteration (loop). Use Enumerable.Any(that uses iterator internally) for simplicity.
var ints = new int[] {1,2,3,4,5};
var any5 = ints.Any( i=> i== 5);
if the list is not that big why dont you loop inside the list
foreach(int a in MyList)
{
if(a == "that_value")
{
break;
}
}

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