get foreach sequence number on an array - c#

I have an array s[],I'm setting it with:
string [] s;
s = data.Split(',');
after I can getting elements from s with foreach:
foreach (string c in s)
{
list.Items.Add(c);
}
but I want to write the seqeunce of c near to c value i.e it'll show in list:
0 hello
1 world
2 earth
I'm not using a counter in foreach,is there another way?

You have to use a counter. You can use one in foreach, or use a for loop and use its counter.
Edit: well if you start with an empty list you could use list.Items.Count in the loop to print the current count of items in the list although this is really not a good way to do that.
// ugly
foreach (string c in s)
{
list.Items.Add(list.Items.Count + " " + c);
}

The obvious thing would be to use a regular loop:
for (int i = 0; i < c.Length; i++) {
list.Items.Add(i.ToString() + " " + c[i]);
}
If you absolutely want to use foreach and no counter variable, you can use Select to bundle each string with its index:
foreach (var c in s.Select((str, i) => new { Value = str, Index = i })) {
list.Items.Add(c.Index.ToString() + " " + c.Value);
}

no there is no other way with given your code.
either you do this:
string [] s= {"0 Hello","1 World", "2 earth"};
//your simple foreach loop
or you do this:
int counter=0;
foreach (string c in s)
{
list.Items.Add(counter++ + " " + c);
}
or change your code, use a for loop
foreach (int i=0;i<s.Length;i++)
{
list.Items.Add(i + " " + c[i]);
}

Related

Exception while copying the array using a foreach loop

Can someone tell me why I'm seeing below exception when I use a foreach loop?
Unhandled Exception: System.IndexOutOfRangeException:
Index was outside the bounds of the array.
but I don't see this exception if I use for loop.
One thing I have noticed is index is starting at 1 if I use foreach loop.
int[] array1 = new int[] { 1, 2, 3 };
int[] array2 = new int[] { 4, 5, 6 };
int[] mergedarray = new int[array1.Length+array2.Length];
array1.CopyTo(mergedarray, 0);
array2.CopyTo(mergedarray, array1.Length);
Console.WriteLine(mergedarray.Length);
//for (int i = 0; i < mergedarray.Length; i++)
//{
// Console.WriteLine(mergedarray[i]); ;
//}
foreach (var item in mergedarray)
{
Console.Write(mergedarray[item] + " ");
}
The issue is with following line
foreach (var item in mergedarray)
{
Console.Write(mergedarray[item] + " ");
}
This needs to be
foreach (var item in mergedarray)
{
Console.Write(item + " ");
}
foreach doesn't give you a index, instead it gives you the item directly out of the array, what you did only worked for you because the arrays were of the int type. You only need a index if you use for. In-depth: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in
And your "index" started with 1 because your array started with that number.
The correct solution would be:
foreach (var item in mergedarray)
{
Console.Write(item + " ");
}
Pro tip:
You can easily join array items into a string using string.Join (https://learn.microsoft.com/en-us/dotnet/api/system.string.join).
It takes first a seperator string or char, in your case the space ' ' or " ", and afterwards you array.
var joinedArray = string.Join(' ', mergedarray);
With regards, 2gjava.

How are strings terminated in C#?

This program throws ArrayIndexOutOfBoundException.
string name = "Naveen";
int c = 0;
while( name[ c ] != '\0' ) {
c++;
}
Console.WriteLine("Length of string " + name + " is: " + c);
Why is it so?
If strings are not null-terminated. How strings are getting handled in C#?
How can I get the length without using string.Length property?
I'm confused here.!
C# does not use NUL terminated strings as C and C++ does. You must use the Length property of the string.
Console.WriteLine("Length of string " + name + " is: " + name.Length.ToString());
or by using formatters
Console.WriteLine("Length of string '{0}' is {1}.", name, name.Length);
public static void Main()
{
unsafe
{
var s = "Naveen";
fixed (char* cp = s)
{
for (int i = 0; cp[i] != '\0'; i++)
{
Console.Write(cp[i]);
}
}
}
}
// prints Naveen
In C/C++ string is stored in is a char array AFAIR without intelligence and behaviour. Therefore, to indicate that such array ends somewhere, one must have added \0 at the end.
On the other hand, in C#, string is a container (a class with properties and methods); as a side note you can assign null to its instantiated object. You don't need to add anything to it to indicate where it ends. The container controlls everything for you. As such, it also has iterator (or enumerator in C# i think). That means you can use foreach and LINQ expressions to iterate over it.
Having said that, you could use a simple counter in a code similar to this to get a length of a string:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LengthOfString
{
class Program
{
static void Main(string[] args)
{
string s = "abcde\0\0\0";
Console.WriteLine(s);
Console.WriteLine("s.Length = " + s.Length);
Console.WriteLine();
// Here I count the number of characters in s
// using LINQ
int counter = 0;
s.ToList()
.ForEach(ch => {
Console.Write(string.Format("{0} ", (int)ch));
counter++;
});
Console.WriteLine(); Console.WriteLine("LINQ: Length = " + counter);
Console.WriteLine(); Console.WriteLine();
//Or you could just use foreach for this
counter = 0;
foreach (int ch in s)
{
Console.Write(string.Format("{0} ", (int)ch));
counter++;
}
Console.WriteLine(); Console.WriteLine("foreach: Length = " + counter);
Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); Console.WriteLine();
Console.WriteLine("Press ENTER");
Console.ReadKey();
}
}
}
You are trying to access a character at an index which is not available according to name length. You may solve it this way:
string name = "Naveen";
int c = 0;
while (c < name.Length)
{
c++;
}
However there is no need to count the length of a string in c# this
way. You can try simply name.Length
EDIT: based on what #NaveenKumarV provide in comments if you want to check for \0 characters then as others said you may try ToCharArray method. Here is the code:
var result = name.ToCharArray().TakeWhile(i => i != '\0').ToList();

How to delete an element from Arraylist in C#

Lets say I have this loop and I put the data in an ArrayList:
int Num1 = Int32.Parse(textBox1.Text);
int Num2 = Int32.Parse(textBox2.Text);
ArrayList ItemList = new ArrayList();
while (Num1 <= Num2)
{
ItemList.Add(Num1);
Num1++;
}
And I have another loop to read my Arraylist:
foreach (int item in ItemList)
{
listBox1.Items.Add("Number " + item.ToString() + ",");
}
Which gives this result:
Number 1,
Number 2,
Number 3,
Number 4,
I need to remove the last comma in the last item and get this result:
Number 1,
Number 2,
Number 3,
Number 4
I've tried this:
foreach (int item in ItemList)
{
listBox1.Items.Add("Number " + item.ToString().Trim(',') + ",");
}
But it doesn't work. Can someone please tell me what I did wrong, and how I can fix it?
See if this works for your purposes:
var result = string.Join("," + Environment.NewLine, itemList.ToArray());
Forgot the "Number" part:
var result = string.Join(", " + Environment.NewLine, itemList.ToArray().Select(x => "Number " + x));
listBox1.Items.Add("Number " + item.ToString() +
ItemList.IndexOf(item) == ItemList.Count - 1 ? string.Empty : ",");
you should not modify the item of your collection inside a foreach.
May be you should try to modify your collection ItemList before the foreach that shows your result .
You can make somthing like this (before the foreach that shows your results):
ItemList[ItemList.Length-1] = ItemList[ItemList.Length-1].SubString(0,ItemList.Length -2);
How about this:
foreach (int item in ItemList)
{
if (listBoxOne.Items == null)
{
listBox1.Items.Add("Number " + item.ToString());
}
else
{
listBox1.Items.Add(",\n" + "Number " + item.ToString());
}
//Or more simply below
listBoxOne.Items.Add = listBoxOne.Items == null ? ("Number " + item.ToString()) : (",\n" + "Number " + item.ToString());

Using a 'foreach' loop with stringArray in C#

I am writing a program which should display the items from an array in a foreach loop.
I wanted to change the elements of the array by adding a string "sad" to each element, but when run the program the array stays the same.
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
string[] stringArray = {"hey", "Tom"};
for (int i = 0; i < stringArray.Length; i++ )
{
stringArray[i] += " dad";
Console.WriteLine(stringArray[i]);
}
Array.Resize(ref stringArray, stringArray.Length + 1);
// Add bob to the last element of the array
stringArray[stringArray.Length - 1] =" bob";
foreach (string s in stringArray)
{
string b = s + "sad";
Console.WriteLine(s);
//Console.WriteLine(stringArray);
}
}
}
}
foreach (string s in stringArray)
{
string b = s + "sad";
// ...
}
Here you are creating a new string, completely unrelated to the string in the string-array. You haven't changed the old string (you can't; strings are immutable). You then simply drop this new longer string on the floor - you aren't updating the array etc.
Try instead something like:
for(int i = 0 ; i < stringArray.Length ; i++)
{
stringArray[i] = stringArray[i] + "sad";
}
This replaces every item in the array with a new string. Note that you can't update a list/collection/array etc while iterating with foreach - that can break the iterator. Hence the for loop instead.
Apart from what Chris said, you could simply use LINQ to achieve what you want:
string[] newStringArray = stringArray
.Select(s => s + "sad")
.ToArray();
string b = s + "sad";
Console.WriteLine(s);
//Console.WriteLine(stringArray);
At no point in your code do you alter values in the array. You create a new string from each value in the array, concatenated with the string "sad".
Solution
You can not alter a for-each variable. You'll get a message like:
Cannot assign to 's' because it is a 'foreach iteration variable'.
Instead, settle for a simple for loop.
for(int x = 0; x < stringArray.length; x++)
{
stringArray[x] = stringArray[x] + "sad";
}
Look at this part of the code:
string b = s + "sad";
Console.WriteLine(s);
You are concatenating the string in s with the string "sad", and storing in the variable b. Then you display the content of the variable s. If you would display the content of the variable b isntead, there would be a sad at the end of each string.

displaying characters and how many times they appear?

I get a string from the user and then put it in a char array. Now I want to display all the characters in the string along with how many times they appear. My code is as follows Please Correct me ?
using System;
class count
{
public void charcount()
{
int i ;
int count = 0;
string s;
Console.WriteLine("Enter the String:");
s = Console.ReadLine();
char[] carr = s.ToCharArray();
for(i = 0; i < carr.Length; i++)
{
for(int j = 1; j < carr.Length; j++)
{
if(carr[j] == carr[i])
{
count++;
}
else
{
return;
}
Console.WriteLine("The Character " + carr[i] + " appears " + count);
}
}
}
static void Main()
{
count obj = new count();
obj.charcount();
}
}
Well, your code will at least have problems due to the fact that you don't build a list of unique characters, you find them in the original string. Any string with characters that appear multiple times will show odd results.
Here's a LINQ expression that calculates the information for you (you can run this in LINQPad to immediately see the results):
void Main()
{
string s = "This is a test, with multiple characters";
var statistics =
from c in s
group c by c into g
select new { g.Key, count = g.Count() };
var mostFrequestFirst =
from entry in statistics
orderby entry.count descending
select entry;
foreach (var entry in mostFrequestFirst)
{
Debug.WriteLine("{0}: {1}", entry.Key, entry.count);
}
}
Output:
: 6 <-- space
t: 5
i: 4
s: 4
h: 3
a: 3
e: 3
l: 2
c: 2
r: 2
T: 1
,: 1
w: 1
m: 1
u: 1
p: 1
If you can't use LINQ, here's an example that doesn't use that:
void Main()
{
string s = "This is a test, with multiple characters";
var occurances = new Dictionary<char, int>();
foreach (char c in s)
{
if (occurances.ContainsKey(c))
occurances[c] = occurances[c] + 1;
else
occurances[c] = 1;
}
foreach (var entry in occurances)
{
Debug.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
}
It looks like you want an outer loop and an inner loop, and for each char in the array, you want to compare to each that follows with int j = 1. In that case, you want int j = i + 1 in the inner loop:
for (int i = 0; i < carr.Length; i++)
{
for (int j = i + 1; j < carr.Length; j++)
{
}
}
But your return statement exits the function right in the middle of things. You need to let the loops complete, so you want to remove that return.
Your Console.WriteLine executes on every iteration of the inner loop, but you really only want it to iterate on the outer loop -- once for each character of the string and not once for every combination of i and j. So you need to push that to the outer loop, outside of the inner loop.
Also, you need to reset the count every time you begin another iteration of the outer loop, because you are counting again, and, you want to start counting at 1 not zero when you find a character because it just appeared once as you first reach it.
And as Lasse points out, you'll get strange output when you hit the same character as you move along the outer loop. An easy way to prevent that is to set the further (rightwards) char[j] to '\0' (null character) on every match, and then in the outer loop, ignore null characters in your counting for example by using continue, effectively culling them as you go along:
for(int i = 0; i < carr.Length; i++)
{
if (carr[i] == '\0')
{
continue; // skip any further chars we've already set to null char
}
int count = 1;
for (int j = i + 1; j < carr.Length; j++)
{
if(carr[j] == carr[i])
{
carr[j] = '\0'; // don't look for this char again later
count++;
}
}
Console.WriteLine("The Character " + carr[i] + " appears " + count);
}
My first thought would be to use a Dictionary as Daniel suggests, like this:
var dict = new Dictionary<char, int>();
string s = "This is a test, with multiple characters";
foreach (var c in s)
{
if (dict.ContainsKey(c))
{
dict[c]++;
}
else
{
dict[c] = 1;
}
}
foreach (var k in dict.Keys)
{
Console.WriteLine("{0}: {1}", k, dict[k]);
}
But I like the elegant LINQ solutions.
If you would have tested your code, you would have realized, that the code is very wrong.
Some of its problems:
You have only one count variable, although you want to count the occurences of all characters in your string
You are comparing the string with itself and return from your method, as soon, as the characters don't match.
The right way would be to use a Dictionary<char, int> to hold the count for each character, something like this:
var counts = new Dictionary<char, int>();
foreach(var c in s)
{
int count;
if(!counts.TryGetValue(c, out count))
{
counts.Add(c, 1);
}
else
{
++counts[c];
}
}
I didn't use LINQ on purpose, because I don't think you would understand that code. That's no offence.
If you want to go the LINQ way, this is a fairly brief way to do it (which I realize is pretty much the same as Lasse V. Karlsen's answer, only using different syntax):
var s = Console.ReadLine();
foreach (var group in s.GroupBy(c => c).OrderByDescending(g => g.Count()))
{
Console.WriteLine(" {0}: {1}", group.Key, group.Count());
}
The logic is the same whatever approach you use:
Identify each unique character
Count how many times each character occurs in the text
Output the result
In my code sample, s.GroupBy(c => c) takes care of the first two steps. The call OrderByDescending(g => g.Count()) will just sort the result so that more frequent characters come first. Each element in the result has a Key property (the character) and (amongst others) a Count() method that will return the number of occurrences for that character.

Categories