C# modify list of string without iterating - c#

I have a List which is returned to me from a 3rd party. Each string in the list ends in "mph" and I would like to remove the "mph". The obvious answer is to foreach over the list but I didn't know if there was a more efficient way to do it.
Thanks.

in a word, no. Something has to pass over the list in order to modify it. A for loop is probably the most efficient way though not necessarily the most concise

You have to iterate over the list to touch each item and make a change.
The easiest way to do this is via linq:
var originallist = new List<string> { "50mph", "35mph", "100mph" };
var newlist = list.Select(s => s.Substring(0, s.Length - 3));

You can use LINQ instead of a foreach loop:
list.Select( s => s.Substring(0, s.Length - 3) )

you can use LINQ for that purpose. Something like this might works :
var noMph = theList.Select(p => p.Replace("mph", "").ToList();

Simple Answer : You Can't
One way or another you have to perform a iteration.
it may be :
foreach
for
List.ForEach

Well you can write
mylist.Select(s=>s.Substring(0, s.Length-3));//Can add .ToList() here
But that is using a loop. You don't have to write the foreach at least :)

this will work
List<string> newList = new List<string>();
mylist.ForEach((item)=>
{
item=item.Replace("mph","");
newlist.Add(item);
});

Related

Can I initialize a list from an expression in a simple way, similar to Python?

Let's say I have a function that returns an object:
public object toto() {}
Or in python:
def toto():
return "something"
I want to initialize a list of n elements in a very simple way, in Python I would do:
l = [toto() for i in range(1, n+1)]
Is there a simple, similar way, of doing that in C#, avoiding loops ?
Thanks !
You can use Enumerable.Range:
var l = Enumerable.Range(0, n + 1).Select(i => "something" + i);
If you want to "consume" it you could use a foreach:
foreach(string s in l)
{
Console.WriteLine(s);
}
or create a new List<string> or string[]:
List<string> stringList = l.ToList();
string[] stringArray = l.ToArray();
That of courses also uses loops, just you don't see them.
Note that if you often need to use it, you should really create a collection from it(as shown above). Otherwise you will always execute the LINQ query (Select is using deferred execution). Read this blog to understand the concept: https://codeblog.jonskeet.uk/2010/03/25/just-how-lazy-are-you/

C# - check if substring is present in arraylist of strings

Suppose I've an Arraylist(arr1) like the below
"String1 is present"
"String2 is present"
"String3 is present"
i wanted to see if 'String2' is present in this arraylist. i've done something like the below:
var containsstringmatch = arr1.OfType<string>().Any(arg=>arg.Contains("String2"));
if (containsstringmatch==true)
{
IEnumerable v1 = arr1.OfType<string>().Where(arg=>arg.Contains("String2"));
foreach (string s in v1)
{
st1 = s;
}
Console.WriteLine(st1);
}
which gives me the below output which is good:
"String2 is present"
I wanted to see if this can be achieved without me using the foreach loop. Can someone please provide suggestions as to how to do it.
Thanks
If you want only to print the first string that contains the search, you can use FirstOrDefault():
var foundString = arr1.OfType<string>().FirstOrDefault(arg => arg.Contains("String2"));
Console.WriteLine(string.IsNullOrEmpty(foundString) ? "Not found" : foundString);
Also, as Aomine wrote in his answer - ArrayLists where good when we worked with .Net 1.1. Since .Net 2.0 introduced generics, ArrayLists should be avoided.
As Rufus L wrote in his comment, your current code gets the last string containing the search string, not the first. If you want the last and not the first, you can simply use LastOrDefault instead of FirstOrDefault.
I'd avoid using ArrayList in this day and age in .NET, instead, favor the List<T> (if possible).
As for:
I wanted to see if this can be achieved without me using the foreach
loop.
if by this you mean that you want to avoid the foreach construct and perform everything inline:
arr1.OfType<string>()
.Where(arg => arg.Contains("String2"))
.ToList()
.ForEach(s => Console.WriteLine(s));
or if you just want to find the last element satisfying the said criteria:
var result = arr1.OfType<string>().LastOrDefault(arg => arg.Contains("String2"));
There is no way to do this without a foreach or for loop. But you can create an extension method that will move the code out of your method.
public static class ConsoleExtensions
{
public static void WriteToConsole(this IEnumerable<string> list)
{
foreach (string item in list)
Console.WriteLine(item);
}
}
usage:
arr1.OfType<string>().Where(arg=>arg.Contains("String2")).WriteToConsole();

how to iterate a dictionary<string,string> in reverse order(from last to first) in C#?

I have one Dictionary and added some elements on it.for example,
Dictionary<string, string> d = new Dictionary<string, string>();
d.Add("Content","Level0");
d.Add("gdlh","Level1");
d.Add("shows","Level2");
d.Add("ytye","Level0");
In C#, Dictionary keeps elements in natural order.But i now want to iterate those values from last to first(ie, Reverse order).i mean,
first i want to read ytye then shows,gdlh and finally Content.
Please guide me to get out of this issue...
Just use the Linq extension method Reverse
e.g.
foreach( var item in d.Reverse())
{
...
}
Use LINQ Reverse, but note that does not reverse in place:
var reversed = d.Reverse();
But note that this is not a SortedDictionary, so the order is not necessarily guaranteed in the first place. Perhaps you want OrderByDescending instead?
Maybe OrderByDescending on the key. Like this:
d.OrderByDescending (x =>x.Key)
Foreach like this:
foreach (var element in d.OrderByDescending (x =>x.Key))
{
}
It's available with Linq: d.Reverse()

c# string.replace in foreach loop

Somehow I can't seem to get string replacement within a foreach loop in C# to work. My code is as follows :
foreach (string s in names)
{
s.Replace("pdf", "txt");
}
Am still quite new to LINQ so pardon me if this sounds amateurish ;)
You say you're after a LINQ solution... that's easy:
var replacedNames = names.Select(x => x.Replace("pdf", "txt"));
We don't know the type of names, but if you want to assign back to it you could potentially use ToArray or ToList:
// If names is a List<T>
names = names.Select(x => x.Replace("pdf", "txt")).ToList();
// If names is an array
names = names.Select(x => x.Replace("pdf", "txt")).ToArray();
You should be aware that the code that you've posted isn't using LINQ at all at the moment though...
Strings in C# are immutable (does not change), so s.Replace will return a new string. Unfortunately this means you cannot use foreach to do the update. If names is an array this should work:
for(int i = 0; i < names.Length; i++)
{
names[i] = names[i].Replace("pdf", "txt");
}
As others have mentioned you'd need to use a for loop to do this in-place. However, if you don't need the operation to be done in-place (i.e. the results can be a different collection), then you could also do it as a linq query, e.g.
var results = from name in names select name.Replace("pdf", "txt");
One thing though - it looks like you are trying to change the extension of some file names. If that's what you are trying to do then I'd recommend Path.ChangeExtension which is specifically designed for this purpose.
var results = from name in names select Path.ChangeExtension(name, "txt");
s.Replace is a function so you would like s=s.Replace().. although it's better to use StringBuilder. (see upper answer)
Why use replace? It will make the application slow. Use regex instead:
http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.replace.aspx

.NET / C# - Convert List to a SortedList

What is the best way to convert a List to SortedList? Any good way to do it without cycling through it? Any clever way to do it with an OrderBy()?
WRAP UP
Please read all answers and comments.
Do you mean:
you have a List<T> and wish it to be sorted in place?
you have a List<T> and wish to create another 'list' which is itself sorted
you have a List<T> and wish to make a SortedList<T,T> where the key is the same as the value
Assuming input:
var x = new List<int>() { 3, 2, 1 };
1 is trivial
x.Sort();
2 is trivial
// sx is an IOrderedEnumerable<T>, you can call ToList() on it if you want
var sx = x.OrderBy(i => i);
3 is trivial with a copy
var s = new SortedList<int,int>(t.ToDictionary(i => i));
and more efficiently:
var s = new SortedList<int,int>();
foreach (var i in x) { s[i] = [i]; }
I can't see why you would want to do 3 but there you go.
var list = new List<string>();
var sortedList = new SortedList<string, string>(list.ToDictionary(s => s));
Now I have no clue how efficient this is, but it's one line of code :) Also, in this example I just used the string itself as the selector. In a real scenario, you should know ahead of time what you'd like to use as a selector.
Understand that a List<T> is a smart array, and a SortedList<T, U> is a key/value binary tree. Since there's no relationship between their structures, there can't possibly be a more effective way to do it rather than simply taking each element from the list and putting it into the tree.
If you mean "sorted list" instead of "SortedList," then it's trivial to sort your list via either List.Sort() or an appropriate OrderBy().
List unsortedPersons = new List();
// ... Populate unsortedPersons ...
var sorted = from person in unsortedPersons
orderby person.Name
select person;
The LINQ gives you an ISortedEnumerable i believe, which may be good enough for your purposes.

Categories