how to query over a list of numbers in line - c#

This is such a simple question, but I cannot find the answer.
What I am looking for is the lightweight way of enumerating through a list of integers without having to define a new array or list or something. The code shown below represents what I want to do, but it doesn't work.
var x = from z in [] {1, 19, 64, 128, 132}
select new {z, "asdffdghdfgh" };
The bit I need help with, without creating something horrible or another variable, is the {1, 19, .... } inline
Thanks
John

In order to do so you must still instantiate an array. This still allocates the object but you just don't have any reference to it after the query is executed.
// See addition of `new int[]`
var x = from z in new int[] { 1, 19, 64, 128, 132 }
select new { z, x = "someText" };
If you were creating a string[] then you wouldn't have to specify the string word before the [] but you would still have to write new [] {...}

Related

Efficiently finding arrays with the most occurences of the same number

Let's say I have the following nested array:
[
[1, 2, 3],
[4, 7, 9, 13],
[1, 2],
[2, 3]
[12, 15, 16]
]
I only need the arrays with the most occurrences of the same numbers. In the above example this would be:
[
[1, 2, 3],
[4, 7, 9, 13],
[12, 15, 16]
]
How can I do this efficiently with C#?
EDIT
Indeed my question is really confusing. What I wanted to ask is: How can I eliminate sub-arrays if some bigger sub-array already contains all the elements of a smaller sub-array.
My current implementation of the problem is the following:
var allItems = new List<List<int>>{
new List<int>{1, 2, 3},
new List<int>{4, 7, 9, 13},
new List<int>{1, 2},
new List<int>{2, 3},
new List<int>{12, 15, 16}
};
var itemsToEliminate = new List<List<int>>();
for(var i = 0; i < allItems.ToList().Count; i++){
var current = allItems[i];
var itemsToVerify = allItems.Where(item => item != current).ToList();
foreach(var item in itemsToVerify){
bool containsSameNumbers = item.Intersect(current).Any();
if(containsSameNumbers && item.Count > current.Count){
itemsToEliminate.Add(current);
}
}
}
allItems.RemoveAll(item => itemsToEliminate.Contains(item));
foreach(var item in allItems){
Console.WriteLine(string.Join(", ", item));
}
This does work, but the nested loops for(var i = 0; i < allItems.ToList().Count; i++) and foreach(var item in itemsToVerify) gives it a bad performance. Especially if you know that the allItems array can contain about 10000000 rows.
I would remember the items that are already in the list.
First sort your lists by decreasing length, then check for each item if it's already present.
Given your algorithm, the array is not added if even a single integer is in the list already of known integers already.
Therefore I would use the following algorithm:
List<List<int>> allItems = new List<List<int>>{
new List<int>{1, 2, 3},
new List<int>{4, 7, 9, 13},
new List<int>{1, 2},
new List<int>{2, 3},
new List<int>{12, 15, 16}
};
allItems = allItems.OrderByDescending(x => x.Count()).ToList(); // order by length, decreasing order
List<List<int>> result = new List<List<int>>();
SortedSet<int> knownItems = new SortedSet<int>(); // keep track of numbers, so you don't have to loop arrays
// https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.sortedset-1?view=netframework-4.7.2
foreach (List<int> l in allItems)
{
// bool allUnique = true;
foreach (int elem in l)
{
if (knownItems.Contains(elem))
{
// allUnique = false;
break;
}
else
{
// OK, because duplicates not allowed in single list
// and because how the data is constrained (I still have my doubts about how the data is allowed to look and what special cases may pop up that ruin this, so use with care)
// this WILL cause problems if a list starts with any number which has not yet been provided appears before the first match that would cause the list to be discarded.
knownItems.Add(elem);
}
}
// see comment above near knownItems.Add()
/*
if (allUnique)
{
result.Add(l);
foreach (int elem in l)
{
knownItems.Add(elem);
}
}
*/
}
// output
foreach(List<int> item in result){
Console.WriteLine(string.Join(", ", item));
}
Instead of looping over your original array twice nestedly (O(n^2)), you only do it once (O(n)) and do a search in known numbers (binary search tree lookup: O(n*log2(n))).
Instead of removing from the array, you add to a new one. This uses more memory for the new array. The reordering is done because it is more likely that any subsequent array contains numbers already processed. However sorting a large amount of lists may be slower than the benefit you gain if you have many small lists. If you have even a few long ones, this may pay off.
Sorting your list of lists by the length is valid because
what is to happen if a list has items from different lists? say instead of new List{2, 3} it was new List{2, 4}?
That unexpected behavior. You can see the ints as an id of a person. Each group of ints forms, for example, a family. If the algorithm creates [2, 4], then we are creating, for example, an extramarital relationship. Which is not desirable.
From this I gather the arrays will contain subsets of at most only one other array or be unique. Therefore the Order is irrelevant.
This also assumes that at least one such array would contain all elements of such subsets (and therefore be the longest one and come first.)
The sorting could be removed if it were not so, and should probably be removed if in doubt.
For example:
{1, 2, 3, 4, 5} - contains all elements that future arrays will have subsets of
{1, 4, 5} - must contain no element that {1,2,3,4,5} does not contain
{1, 2, 6} - illegal in this case
{7, 8 ,9} - OK
{8, 9} - OK (will be ignored)
{7, 9} - OK (will be ignored, is only subset in {7,8,9})
{1, 7} - - illegal, but would be legal if {1,2,3,4,5,7,8,9} was in this list. because it is longer it would've been earlier, making this valid to ignore.

Checking to see if last 2 numbers in array both exist in 2D array using loops

I have two arrays, one singular and the other 2 dimensional.
int[][] array1 = {
new int [] {1, 22, 3, 44, 5, 66},
new int [] {11, 22, 33, 44, 55, 66},
new int [] {1, 2, 3, 4, 5, 6},
};
int[] array2 = new int[] {1, 2, 3, 5, 66}
I need to create a loop which searches the array1 for both the 2nd last digits in array2, so it would return how many times an array with array1 contains both 5 and 66, which is 1, as the other two only contain 1 of each number.
I already managed to write a function which returns how many times array2 as a whole exists in array1, this new function is effectively a refinement of that.
for (int a = 0; a < array1[i].Length; a++)
{
for (int b = 0; b < array2.Length; b++)
{
if (array2[c] == array1[a][b])
count++;
temp[b] = array1[a][b];
}
}
I feel all would be needed to search for just the last two digits is a slight change to this function, I tried to add in another loop but that didn't work either. How would I go about doing this? I'm using loops and not Contains for a reason since i'm still learning the basics.
The one thing is not clear in question that, does it matter which position the two digits occur in the 2D array?
If ithis is not the case, then you can use Intersect() which produces the set intersection of two sequences by using the default equality comparer to compare values:
var result = array1.Count(x => x.Intersect(array2.Reverse().Take(2)).Count() == 2);
If you have paid an attention we have used this line, for getting last two elements of array1:
array1.Reverse().Take(2);
.NET Fiddle
Additional:
If you want to find if last two elements of arrays in 2D array is equal to last two elements of array1, then you can try LINQ solution:
var result = array1.Count(x=> x.Reverse().Take(2).SequenceEqual(array2.Reverse().Take(2)));
Explanation of used extension methods:
Reverse() inverts the order of the elements in a sequence.
Take() returns a specified number of contiguous elements from the start of a sequence.
SequenceEqual() determines whether two sequences are equal by comparing the elements by using the default equality comparer for their type.
After getting last two elements of both arrays, we will use SequenceEqual() to determine if both arrays are equal.
var res = array1.Where((x) => (x.Contains(array2.Last()) && x.Contains(array2[array2.Length - 2]))).Count();
Explaination:
array1.Where takes every subarray of array1 and filters the ones that
meet a certain condition. The condition being every subarray of
array1 contains the last && next-to-last element of array2.The
Count() methods returns the number of subarrays that meet the
conditions
You can create an array of target values and then count the number of times that the intersection of that array with each subarray in the 2D array contains all the items in the target array:
using System;
using System.Linq;
namespace ConsoleApplication2
{
class Program
{
[STAThread]
private static void Main()
{
int[][] array1 =
{
new [] {1, 22, 3, 44, 5, 66},
new [] {11, 22, 33, 44, 55, 66},
new [] {1, 2, 3, 4, 5, 6},
new [] {1, 66, 3, 4, 5, 6} // This one has the target items out of order.
};
int[] array2 = {1, 2, 3, 5, 66};
// Extract the targets like this; it avoids making a copy
// of array2 which occurs if you use IEnumerable.Reverse().
int[] targets = {array2[array2.Length - 2], array2[array2.Length - 1]};
// Count the number of times that each subarray in array1 includes
// all the items in targets:
int count = array1.Count(array => array.Intersect(targets).Count() == targets.Length);
Console.WriteLine(count);
}
}
}

Specifying a size when declaring a List of Arrays

As the question states, is there an alternate way to do this?:
decimal[] decimal_array = new decimal[12];
List<decimal> decimal_list = new List<decimal>(3);
// want to combine the two
List<decimal[]> decimal_list_array = new List<decimal[12]>(3); // doesn't compile
I understand that this won't work because "decimal[12]" isn't a type, but it would be nice and concise to set the size of the structure when I declare it, instead of having to write decimal_list_array.Add(new decimal[12]) a bunch of times.
I want to be able to operate primarily by index on each instance of an object in the list, but otherwise I don't care about ordering of the actual objects in the list.
Edit: The initial size of the structure will be known when declared, but this is just the minimum # of instances of the List<decimal[]>
You can use LINQ
var list = Enumerable.Range(0, 3).Select(x => new decimal[12]).ToList();
If you want to constrain the size of the inner array and outter list, then perhaps what you need is a multi-dimensional array instead.
decimal[,] decimalListArray = new decimal[3,12];
As you said, new List<decimal[12]>(3) won't work because decimal[12] is not a type, but even if it did, you're not actually constraining the list to have 3 elements either. 3 will be the initial capacity, but if a fourth item is added, the capacity will grow. Lists are dynamic by definition.
You can do the following:
decimal[] dec_array = new decimal[12] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
List<decimal> dec_list = new List<decimal>(3) { 12, 13, 14 };
List<decimal> listComb = dec_array.ToList().Union(dec_list).ToList();
//you can change order by doing so: dec_list.Union(dec_array.ToList()).ToList();
don't forget to 'using System.Linq;'

How do Arrays work in C#?

I know that they are used to store data, but I have a difficult time understanding exactly how to use them in a program.
In addition, I found this site with a tetris clone tutorial (the actual tutorial is missing). It uses arrays, but I can't really make sense of how it works.
Here's an example of the code -
public int[, ,] TShape = new int[4, 4, 2]
{
{{1, 0}, {0, 1}, {1, 1}, {2, 1}},
{{1, 0}, {0, 1}, {1, 1}, {1, 2}},
{{0, 0}, {1, 0}, {2, 0}, {1, 1}},
{{0, 0}, {0, 1}, {1, 1}, {0, 2}}};
Could it be that I'm looking too hard into this, or perhaps there's something I'm not grasping about it?
It would be clearer if formatted this way:
public int[, ,] TShape = new int[4, 4, 2]
{
{ {1, 0}, // <- this is int[2]
{0, 1},
{1, 1},
{2, 1} }, // <- the last four lines are an int[4,2]
{ {1, 0},
{0, 1},
{1, 1},
{1, 2} }, // <- another int[4,2]
{ {0, 0},
{1, 0},
{2, 0},
{1, 1} }, // <- third int[4,2]
{ {0, 0},
{0, 1},
{1, 1},
{0, 2} } // <- fourth and last int[4,2]
}; // <- The whole thing is int[4, 4, 2]
"Well I've been having a hard time
understanding how to use arrays. I
know they are used for storing data,
but I have yet to find any resource
that gives a clearer explanation than
that."
I'll try to give you an analogy: array is to programming like a file cabinet is to an office. The only difference is that a file cabinet is restricted to what it can hold: i.e. files... the only restriction for arrays is that it must hold items of the same type, but the actual type of the item can be nearly anything. Arrays can not only hold data, but objects, other arrays, other containers, etc.
So what can you do with an array in programming? Well a LOT of stuff! Let's look at several examples:
Financial: an array can hold the stock prices for today.
Gaming: an array can hold the 3D models that are used on a level.
Military: an array can hold all of the targets identified by a targeting system.
etc...
The main purpose of arrays is to contain various things and allow us to iterate over them. For example:
// Financial
int[] stockPrices = new int[4]{ 15, 14, 18, 16 }; // contains four prices
foreach( int price in stockPrices )
{
MakeTransaction(price);// calls a function that makes a transaction at the price: e.g. buy/sell
}
// Gaming
3DModel[] gameModels = new 3DModel[4]{ new Tank(), new Truck(), new Soldier(), new Building()}; // contains 3D models
foreach( 3DModel model in gameModels )
{
model.Draw();// calls a function of each 3DModel that draws the model on the screen
}
// Military
Target[] targets = new Target[4]{ new Tank(), new Helicopter(), new APC(), new Truck()}; // contains targets
foreach( Target target in targets )
{
Attack(target);// calls an attack function which initiates an attack on each target
}
The possibilities are endless! Arrays are a subset of containers and containers are an integral part of programming. Does that help?
Straight from the horse's mouth: http://msdn.microsoft.com/en-us/library/system.array.aspx
Those details will come in handy after you have gone through online tutorials such as this http://www.functionx.com/csharp/Lesson21.htm
Imagine you have 10 boxes. Now you want to clearly tell someone which box you are talking about. So you assign numbers to them, from 0 to 9. What you have now is an array of boxes, defined as:
box[ 10 ]
The number in the brackets tells you, how many of them are there. By default they are numbered from 0 to 9 (some languages allow to change this, but lets skip that for now). So if you are talking about the fifth box, its box[ 4 ] (since we index from 0!). Now imagine you open the box and see that there are five balls in it. This defines an array:
box[ 10 ][ 5 ]
A two dimensional array. How do you tell your friend which ball do you want to talk about? Again, you number them, this time from 0 to 4. How do you specify say the third ball in the seventh box? Simple: box[ 6 ][ 2 ]. And so on. Hope that helps.
In your question, you're stating the Tetris game which uses an array. That is a good use of arrays in whatever language you're using.
You have to see the Tetris play yard as the array. Let's say this play yard is a 20 spaces on the X axis, and 100 spaces on the Y axis. What tells you whether you have a piece on a space, is when you have the integer value 1, and you get an integer value of 0 for empty spaces. We then get:
var tetrisPlayYard = new int[20][100];
You now have to initialize each positions of the board to 0 in order to mark them as empty spaces, so no pieces have ever been placed already.
for(int xAxisIndex = 0; xAxisIndex < tetrisPlayYard.GetLength(0); ++xAxisIndex )
for (int yAxisIndex = 0; yAxisIndex < tetrisPlayYard.GetLength(1); ++ yAxisIndex)
tetrisPlayYard[xAxisIndex][yAxisIndex] = 0;
We now know that no pieces is on board as each array's positions are set to 0.
Then, when we place, let's say a four spaces straight line horizontally at the bottom-right of the board, we would then have to address 4 spaces, and set their values to 1 to indicate there is a piece on these spaces.
tetrisPlayYard[19][99] = 1;
tetrisPlayYard[18][99] = 1;
tetrisPlayYard[17][99] = 1;
tetrisPlayYard[16][99] = 1;
This tells that you have a four spaces straight line. Your algorithm should work around this logic to display the bars, the cubes, etc. while playing the game.
In conclusion, use arrays whenever a finite space is known, and that you know that it won't be required to resize it dynamically. Otherwise, a Collection should be used.

C# - Array Copying using CopyTo( )-Help

I have to copy the following int array in to Array :
int[] intArray=new int[] {10,34,67,11};
i tried as
Array copyArray=Array.CreateInstance(typeof(int),intArray.Length,intArray);
intArray.CopyTo(copyArray,0);
But ,it seems i have made a mistake,so i did not get the result.
This works:
int[] intArray = new int[] { 10, 34, 67, 11 };
Array copyArray = Array.CreateInstance(typeof(int), intArray.Length);
intArray.CopyTo(copyArray, 0);
foreach (var i in copyArray)
Console.WriteLine(i);
You had one extra "intArray" in your Array.CreateInstance line.
That being said, this can be simplified if you don't need the Array.CreateInstance method (not sure if that's what you're trying to work out, though):
int[] intArray = new int[] { 10, 34, 67, 11 };
int[] copyArray = new int[intArray.Length];
intArray.CopyTo(copyArray, 0);
Even simpler:
int[] intArray = new int[] { 10, 34, 67, 11 };
int[] copyArray = (int[])intArray.Clone();
Are you aware that an int[] is already an Array? If you just need to pass it to something accepting Array, and you don't mind if it changes the contents, just pass in the original reference.
Another alternative is to clone it:
int[] clone = (int[]) intArray.Clone();
If you really need to use Array.CopyTo then use the other answers - but otherwise, this route will be simpler :)
Try this instead:
int[] copyArray = new int[intArray.Length];
Array.Copy(intArray, copyArray, intArray.Length);
In this particular case, just use
int[] copyArray = (int[]) intArray.Clone();

Categories