I'm trying to find how many elements are in my string array, so I can add to that array from the first empty element.
Here's what I've tried to do:
int arrayLength = 0;
string[] fullName = new string[50];
if (fullName.Length > 0)
{
arrayLength = fullName.Length - 1;
}
and then from that refer to the first available empty element as:
fullName[arrayLength] = "Test";
I can also use this to see if the array is full or not, but my problem is arrayLength is always equal to 49, so my code seems to be counting the size of the entire array, not the size of the elements that are not empty.
Cheers!
you can use this function to calculate the length of your array.
private int countArray(string[] arr)
{
int res = arr.Length;
foreach (string item in arr)
{
if (String.IsNullOrEmpty(item))
{
res -= 1;
}
}
return res;
}
EDIT : To find the first empty element
private int firstEmpty(string[] arr)
{
int res = 0;
foreach (string item in arr)
{
if (String.IsNullOrEmpty(item))
{
return res;
}
res++;
}
return -1; // Array is full
}
I'm trying to find how many elements are in my string array,
array.Length
so I can add to that array from the first empty element.
Array's don't have empty elements; there's always something in there, though it could be null.
You could find that by scanning through until you hit a null, or by keeping track each time you add a new element.
If you're going to add new elements then, use List<string> this has an Add() method that will do what you want for you, as well as resizing when needed and so on.
You can likely then just use the list for the next part of the task, but if you really need an array it has a ToArray() method which will give you one.
So if you want to use the array instead of a list you still simply can get the number of empty elements like this:
int numberOfEmptyElements = fullName.Count(x => String.IsNullOrEmpty(x));
Try the below code
string[] fullName = new string[50];
fullName[0] = "Rihana";
fullName[1] = "Ronaldo";
int result = fullName.Count(i => i != null);
in result you will have the number of occupied positions. In this case 2, cause 2 arrays are filled. From there you can count the empty. :)
Related
I want to trim all the white-spaces and empty strings only from the starting and ending of an array without converting it into a string in C#.
This is what I've done so far to solve my problem but I'm looking for a bit more efficient solution as I don't want to be stuck with a just works solution to the prob
static public string[] Trim(string[] arr)
{
List<string> TrimmedArray = new List<string>(arr);
foreach (string i in TrimmedArray.ToArray())
{
if (String.IsEmpty(i)) TrimmedArray.RemoveAt(TrimmedArray.IndexOf(i));
else break;
}
foreach (string i in TrimmedArray.ToArray().Reverse())
{
if (String.IsEmpty(i)) TrimmedArray.RemoveAt(TrimmedArray.IndexOf(i));
else break;
}
return TrimmedArray.ToArray();
}
NOTE: String.IsEmpty is a custom function which check whether a string was NULL, Empty or just a White-Space.
Your code allocates a lot of new arrays unnecessarily. When you instantiate a list from an array, the list creates a new backing array to store the items, and every time you call ToArray() on the resulting list, you're also allocating yet another copy.
The second problem is with TrimmedArray.RemoveAt(TrimmedArray.IndexOf(i)) - if the array contains multiple copies of the same string value in the middle as at the end, you might end up removing strings from the middle.
My advice would be split the problem into two distinct steps:
Find both boundary indices (the first and last non-empty strings in the array)
Copy only the relevant middle-section to a new array.
To locate the boundary indices you can use Array.FindIndex() and Array.FindLastIndex():
static public string[] Trim(string[] arr)
{
if(arr == null || arr.Length == 0)
// no need to search through nothing
return Array.Empty<string>();
// define predicate to test for non-empty strings
Predicate<string> IsNotEmpty = string s => !String.IsEmpty(str);
var firstIndex = Array.FindIndex(arr, IsNotEmpty);
if(firstIndex < 0)
// nothing to return if it's all whitespace anyway
return Array.Empty<string>();
var lastIndex = Array.FindLastIndex(arr, IsNotEmpty);
// calculate size of the relevant middle-section from the indices
var newArraySize = lastIndex - firstIndex + 1;
// create new array and copy items to it
var results = new string[newArraySize];
Array.Copy(arr, firstIndex, results, 0, newArraySize);
return results;
}
I like the answer by Mathias R. Jessen as it is efficient and clean.
Just thought I'd show how to do it using the List<> as in your original attempt:
static public string[] Trim(string[] arr)
{
List<string> TrimmedArray = new List<string>(arr);
while (TrimmedArray.Count>0 && String.IsEmpty(TrimmedArray[0]))
{
TrimmedArray.RemoveAt(0);
}
while (TrimmedArray.Count>0 && String.IsEmpty(TrimmedArray[TrimmedArray.Count - 1]))
{
TrimmedArray.RemoveAt(TrimmedArray.Count - 1);
}
return TrimmedArray.ToArray();
}
This is not as efficient as the other answer since the internal array within the List<> has to shift all its elements to the left each time an element is deleted from the front.
My problem today is about creating an array from an existing one.
My "parent" array contains elements with two characters.
My new array's elements should contain 20 elements from the "parent" array.
Example:
string[] parentArray = {aa, bb, cc, df, ds, aa, zz, xx, cc, ww, fg, qq, ww, ee,
key: (0) (1) (2) (3) (4) (6) (7) (8) (9) (10)........ rr, dd, ss, qq, dd, ss, sa, wq, ee, rr}
string[] childArray = {aabbccdfdsaazzxxccwwfgqqwweerrddssqqddss,.....}
(1)
With some of the extension functions for enumerables you can go a long way here.
int cursor = 0;
List<string> result = new List<string>();
while (cursor < parentArray.Length)
{
result.Add(String.Join("", parentArray.Skip(cursor).Take(20)));
cursor += 20;
}
string[] childArray = result.ToArray();
This function walks over your array, fetches 20 elements (or less in case there aren't 20 elements left) and merges them into a string and add that string to a list. I made use of the String.Join method to concat the string. That works nicely here.
The Skip function and the Take function are extension functions for IEnumerable and do just what they say.
EDIT: I did assume that your source array is longer and may contain multiple blocks of 20 elements that need to be moved to the childArray
EDIT2: In case you have a load of values in your parentArray you may want to go a different way, to get some more performance out of it. In that case I suggest using the StringBuilder.
var builder = new Text.StringBuilder();
List<string> result = new List<string>();
for (int cursor = 0; cursor < parentArray.Length; cursor++)
{
if (builder.Length > 0 && (cursor % 20) == 0)
{
result.Add(builder.ToString());
builder.Length = 0;
}
builder.Append(parentArray[cursor]);
}
/* At this point you can choose to add the remaining elements to the list or not. */
if (builder.Length > 0)
{
result.Add(builder.ToString());
}
string[] childArray = result.ToArray();
Sounds as if a simple LINQ-statement will do what you need:
var myArr = parent.Take(20).ToArray();
This will select the 20 first elements of your parent-array.
EDIT: To do this with all of your elements within parent loop its entries:
List<string> result= new List<string>();
while(parent.Any()) {
result.Add(String.Join("", parent.Take(20).ToArray());
parent = parent.Skip(20).ToArray();
}
Finally convert your list back to an array using result.ToArray.
You can make a for loop on the parent array and add the element inside the array to a string like the following
String str="";
for (int i=0;i<count(parent);i++){
str+=parent[i].tostring();
}
Then make a new string array and at the first index put the str variable...
Hope this help you if this what u r asking for.
I have an array of tags that may appear in console as color tags. There's 37 of them.
So, I do this code:
tagsCT is a string[]
foreach (string tag in tagsCT)
{
if (text.Contains(tag))
{
ArrayList x = new ArrayList();
x.Add(tag);
x.Add(tagsColorValues[k]);
tagss.Add(text.IndexOf(tag));
tags.Add(text.IndexOf(tag) - 1, x);
}
k++;
}
What do I have:
text = "2013-11-11 17:56:14 [INFO] $4/time: $5Changes the time on each world"
What I need to do is find all the color tags in the string. All the possible ones are
in an array string[]
tagsCT = { "$1","$2","$3","$4" }
I show it as an example, but the tags aren't always the same length.
But the problem strikes in these situations:
text = "2013-11-11 17:56:14 [INFO] $4/time: $5Changes the time on each $4world"
The last tag will not be detected. The question is how to prevent it.
You could use a Dictionary<string, IList<int>> instead:
var tagIndices = new Dictionary<string, IList<int>>();
foreach (string tag in tagsCT)
{
IList<int> indices;
if (tagIndices.TryGetValue(tag, out indices))
continue; // to prevent the same indices on duplicate tags, you could also use a HashSet<string> instead of the array
else
{
indices = new List<int>();
tagIndices.Add(tag, indices);
}
int index = text.IndexOf(tag);
while (index >= 0)
{
indices.Add(index);
index = text.IndexOf(tag, index + 1);
}
}
Each tag is stored as key and the value is the list of indices (can be empty).
Here's a demonstration
How about, after you've processed the tag, remove it from the "text" string?
You could also use a for(int i;;i) structure using the IndexOf value.
(sorry, where the hell is he comment button then?)
I'm trying to solve a simple algorithm a specific way where it takes the current row and adds it to the top most row. I know there are plenty of ways to solve this but currently I have a text file that gets read line by line. Each line is converted to an sbyte (there's a certain reason why I am using sbyte but it's irrelevant to my post and I won't mention it here) and added to a list. From there, the line is reversed and added to another list. Here's the code I have for that first part:
List<List<sbyte>> largeNumbers = new List<List<sbyte>>();
List<string> total = new List<string>();
string bigIntFile = #"C:\Users\Justin\Documents\BigNumbers.txt";
string result;
StreamReader streamReader = new StreamReader(bigIntFile);
while ((result = streamReader.ReadLine()) != null)
{
List<sbyte> largeNumber = new List<sbyte>();
for (int i = 0; i < result.Length; i++)
{
sbyte singleConvertedDigit = Convert.ToSByte(result.Substring(i, 1));
largeNumber.Add(singleConvertedDigit);
}
largeNumber.Reverse();
largeNumbers.Add(largeNumber);
}
From there, I want to use an empty list that stores strings which I will be using later for adding my numbers. However, I want to be able to add numbers to this new list named "total". The numbers I'll be adding to it are not all the same length and because so, I need to check if an index exists at a certain location, if it does I'll be adding the value I'm looking at to the number that resides in that index, if not, I need to create that index and set it's value to 0. In trying to do so, I keep getting an IndexOutOfRange exception (obviously because that index doesn't exist). :
foreach (var largeNumber in largeNumbers)
{
int totalIndex = 0;
foreach (var digit in largeNumber)
{
if (total.Count == 0)
{
total[totalIndex] = digit.ToString(); //Index out of Range exception occurs here
}
else
{
total[totalIndex] = (Convert.ToSByte(total[totalIndex]) + digit).ToString();
}
totalIndex ++;
}
}
I'm just at a loss. Any Ideas on how to check if that index exists; if it does not create it and set it's underlying value equal to 0? This is just a fun exercise for me but I am hitting a brick wall with this lovely index portion. I've tried to use SingleOrDefault as well as ElementAtOrDefault but they don't seem to be working so hot for me. Thanks in advance!
Depending on if your result is have small number of missing elements (i.e. have more than 50% elements missing) consider simply adding 0 to the list till you reach neccessary index. You may use list of nullable items (i.e. List<int?>) instead of regular values (List<int>) if you care if item is missing or not.
Something like (non-compiled...) sample:
// List<long> list; int index; long value
if (index >= list.Count)
{
list.AddRange(Enumerable.Repeat(0, index-list.Count+1);
}
list[index] = value;
If you have significant number of missing elements use Dictionary (or SortedDictionary) with (index, value) pairs.
Dictionary<int, long> items;
if (items.ContainsKey(index))
{
items[key] = value;
}
else
{
items.Add(index, value);
}
I have this assignment where I must delete a chosen element from an array, so I came up with this code:
strInput = Console.ReadLine();
for (int i = 0; i < intAmount; i++)
{
if (strItems[i] == strInput)
{
strItems[i] = null;
for (int x = 0; x < intAmount-i; x++)
{
i = i + 1;
strItems[i - 1] = strItems[i];
}
intAmount = intAmount - 1;
}
}
The problem is that, suppose I have an array [1,2,3,4,5,], and I want to delete 1. The output would be [2,3,4,5,5]. This also happens when I choose 2, but it does not happen when I choose any other number.
What am I doing wrong?
I'm assuming you are working with a basic array of strings:
var strItems = new string[] { "1", "2", "3", "4", "5" };
In .NET, that array is always going to be 5 elements long. In order to remove an element, you are going to have to copy the remaining elements to a new array and return it. Setting the value at a position to null does not remove it from the array.
Now, with things like LINQ this is very easy (not shown here), or you could cheat using the List<> collection and do this:
var list = new List<string>(strItems);
list.Remove("3");
strItems = list.ToArray();
But I don't think that's going to teach you anything.
The first step is to find the index of the element you wish to remove. You can use Array.IndexOf to help you out. Let's find the middle element, "3":
int removeIndex = Array.IndexOf(strItems, "3");
If the element was not found, it will return a -1, so check for that before doing anything.
if (removeIndex >= 0)
{
// continue...
}
Finally you have to copy the elements (except the one at the index we don't want) to a new array. So, altogether, you end up with something like this (commented for explanation):
string strInput = Console.ReadLine();
string[] strItems = new string[] { "1", "2", "3", "4", "5" };
int removeIndex = Array.IndexOf(strItems, strInput);
if (removeIndex >= 0)
{
// declare and define a new array one element shorter than the old array
string[] newStrItems = new string[strItems.Length - 1];
// loop from 0 to the length of the new array, with i being the position
// in the new array, and j being the position in the old array
for (int i = 0, j = 0; i < newStrItems.Length; i++, j++)
{
// if the index equals the one we want to remove, bump
// j up by one to "skip" the value in the original array
if (i == removeIndex)
{
j++;
}
// assign the good element from the original array to the
// new array at the appropriate position
newStrItems[i] = strItems[j];
}
// overwrite the old array with the new one
strItems = newStrItems;
}
And now strItems will be the new array, minus the value specified for removal.
Arrays in C# are of a fixed size - once initialized you can only modify items, but you cannot add or remove items. If you want to delete an item from a collection you have two options:
1.) Create a new array that has all members of the original array minus the one you want to remove.
2.) Use a collection type that is resizable and allows to add or remove items like List<T> (List<int> in your case). This is what you would do in the "real world" if your collection is not static.
In your specific implementation i think u miss a break; statement, you should go out from the outer loop when you finish the inner loop. The assignment to null is not useful at all.
If the list is just a list of numbers why are you using strings? use integers directly if it is the case.
Your exercise seems to ask something like this, if you need to remove only one element.
public bool MyDelete(int[] array, int value) // Easy to do for strings too.
{
bool found = false;
for (int i = 0; i < array.Length; ++i)
{
if (found)
{
array[i - 1] = array[i];
}
else if (array[i] == value)
{
found = true;
}
}
return found;
}
This function will returns true if it find the specified falue, false if not.
It will move all items as you describe in your example, but of course, it will not change the size of the array.
Arrays are fixed size.
You cannot change the size of an array, simply, the language don't allows that.
Arrays are, were and will be always fixed size!
To remove an item from an array you should do something this:
public static T[] RemoveAt<T>(T[] array, int index) // hope there are not bugs, wrote by scratch.
{
int count = array.Length - 1;
T[] result = new T[count];
if (index > 0)
Array.Copy(array, 0, result, 0, index - 1);
if (index < size)
Array.Copy(array, index + 1, result, index, size - index);
return result;
}
...
strItems = RemoveAt(strItems, index);
This function will create a new array that contains all elements except the one at the index you specify.
Now, why someone would do something like this instead of using a List or a Dictionary or wathever?
Use directly a List without using an array.
Can use Except method to filter the data
AllData = {10, 30, 20, 50}
FilterData = {30, 20}
Result = AllData.Except(​FilterData)
Result will be {10, 50}
Arrays are a fixed sized, you can't shorten their length without creating a new array. All you can do is store the length of valid elements in the array (ie. after you remove 1 the length is 4).
Also, I'm not sure if the order of elements in your array is important, but if it's not you could swap the first and last elements rather than moving every element after the one that's removed forward 1 position.
An alternative to using an array is using a collection such as an ArrayList which will take care of resizing, removing and keeping a count of the amount of items in it, plus a lot more.
However, since this is homework you might have to use arrays. Either keep track of the length with a variable, as opposed to using array.length, or create a new array each time you want to change the size. If you don't have to use arrays then look at the collections you can use in C#.