String array elements OrderBy itself - c#

If I have a string array like this:
string[] str = new string[]{"abc", "bacd", "pacds"};
Then I need output like below using LINQ:
output: abc, abcd, acdps

This should be what you want:
string[] str = new string[] { "abc", "bacd", "pacds" };
var result = str.Select(c => String.Concat(c.OrderBy(d => d)));
The result is IEnumerable<string> but if you want the result in an string array add .ToArray():
var result = str.Select(c => String.Concat(c.OrderBy(d => d))).ToArray();
The result:

You can use String.Concat(st.OrderBy(c => c)) to order string by its characters.
str.ToList().ForEach((val) => {
val = String.Concat(val.OrderBy(c => c));
});

str.Select(x => x.ToCharArray().OrderBy(c => c).Aggregate("", (s,c)=>s+c))

this just to change the array strings into chars-ordered ones
static void orderChars(string[] str)
{
for (int i = 0; i < str.Length; i++)
str[i] = new string(str[i].OrderBy(c => c).ToArray());
}

As bassfader commented , show your code and say where u stuck , then we can guide you, anyway ..
You can write it like this ,
string[] a = new string[]
{"Indonesian","Korean","Japanese","English","German"};
var sort = from s in a orderby s select s;

Related

Removing strings with duplicate letters from string array

I have array of strings like
string[] A = { "abc", "cccc", "fgaeg", "def" };
I would like to obtain a list or array of strings where any letter appears only one time. I means that "cccc", "fgaeg" will be removed from input array.
I managed to do this but I feel that my way is very messy, unnecessarily complicated and not efficient.
Do you have any ideas to improve this algorythm (possibliy replacing with only one Linq query)?
My code:
var goodStrings = new List<string>();
int i = 0;
foreach (var str in A)
{
var tempArr = str.GroupBy(x => x)
.Select(x => new
{
Cnt = x.Count(),
Str = x.Key
}).ToArray();
var resultArr = tempArr.Where(g => g.Cnt > 1).Select(f => f.Str).ToArray();
if(resultArr.Length==0) goodStrings.Add(A[i]);
i++;
}
You can use Distinct method for every array item and get items with count of distinct items equals to original string length
string[] A = { "abc", "cccc", "fgaeg", "def" };
var result = A.Where(a => a.Distinct().Count() == a.Length).ToList();
You'll get list with abc and def values, as expected

Sorting a list of numeric strings with numerous decimal points

I've got a situation where I need to sort a list of strings that contain three decimal parts in descending order from left-to-right. The real code is a dictionary of <string, object>, but I've simplified it here as I'm in the same predicament either way.
Straight to the code:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<string> perlVersions = new List<string>();
perlVersions.Add("5.26.1_32");
perlVersions.Add("5.24.1_32");
perlVersions.Add("5.8.1_64");
perlVersions.Add("5.24.2_64");
perlVersions.Sort();
perlVersions.Reverse();
foreach (string str in perlVersions) Console.WriteLine(str);
}
}
Output:
5.8.1_64
5.26.1_32
5.24.2_64
5.24.1_32
Now, Everything works well, except that the 5.8.1_64, due to the second part of the number being lower than all others, should be at the bottom.
Is there a special sorting trick I'm missing, or is there a way to further break apart the strings and sort on each individual element?
You could for example split the string and treat the different parts an integers, and then sort by these using some LINQ:
static void Main()
{
List<string> perlVersions = new List<string>();
perlVersions.Add("5.26.1_32");
perlVersions.Add("5.24.1_32");
perlVersions.Add("5.8.1_64");
perlVersions.Add("5.24.2_64");
perlVersions = perlVersions
.Select(x => x.Split(new char[] { '.' }))
.Select(x =>
{
string[] lastParts = x[2].Split(new char[] { '_' });
return new { a = Convert.ToInt32(x[0]), b = Convert.ToInt32(x[1]), c = Convert.ToInt32(lastParts[0]), d = Convert.ToInt32(lastParts[1]) };
})
.OrderBy(x => x.a).ThenBy(x => x.b).ThenBy(x => x.c).ThenBy(x => x.d)
.Select(x => string.Format("{0}.{1}.{2}_{3}", x.a, x.b, x.c, x.d))
.ToList();
perlVersions.Reverse();
foreach (string str in perlVersions) Console.WriteLine(str);
}
Try this one
string[] separator = new string[] { "." };
var result = perlVersions
.OrderByDescending(s => int.Parse(s.Split(separator, StringSplitOptions.None)[1]))
.OrderByDescending(s => int.Parse(s.Split(separator, StringSplitOptions.None)[0]))
.ToList();
Or a fully query syntax version:
var b = from v in perlVersions
let ii = v.Split(".")
.Take(2)
.Select(i => int.Parse(i)).ToArray()
orderby ii[0] descending
orderby ii[1] descending
select v;
You can do you custom sort using Linq
To do so split your string by '.' and then extend each part with '0'
List<string> perlVersions = new List<string>();
perlVersions.Add("5.26.1_32");
perlVersions.Add("5.24.1_32");
perlVersions.Add("5.8.1_64");
perlVersions.Add("5.24.2_64");
perlVersions = perlVersions
.OrderByDescending(v => string.Concat(v.Split('.').Select(x => x.PadLeft(5, '0'))))
.ToList();
This will (temporary) convert "8" to "00008" and "24" to "00024", which make your sort working as expected.

How to find the duplicates in the given string in c#

I want to find the duplicates for a given string, I tried for collections, It is working fine, but i don't know how to do it for a string.
Here is the code I tried for collections,
string name = "this is a a program program";
string[] arr = name.Split(' ');
var myList = new List<string>();
var duplicates = new List<string>();
foreach(string res in arr)
{
if (!myList.Contains(res))
{
myList.Add(res);
}
else
{
duplicates.Add(res);
}
}
foreach(string result in duplicates)
{
Console.WriteLine(result);
}
Console.ReadLine();
But I want to find the duplicates for the below string and to store it in an array. How to do that?
eg:- string aa = "elements";
In the above string i want to find the duplicate characters and store it in an array
Can anyone help me?
Linq solution:
string name = "this is a a program program";
String[] result = name.Split(' ')
.GroupBy(word => word)
.Where(chunk => chunk.Count() > 1)
.Select(chunk => chunk.Key)
.ToArray();
Console.Write(String.Join(Environment.NewLine, result));
The same princicple for duplicate characters within a string:
String source = "elements";
Char[] result = source
.GroupBy(c => c)
.Where(chunk => chunk.Count() > 1)
.Select(chunk => chunk.Key)
.ToArray();
// result = ['e']
Console.Write(String.Join(Environment.NewLine, result));
string name = "elements";
var myList = new List<char>();
var duplicates = new List<char>();
foreach (char res in name)
{
if (!myList.Contains(res))
{
myList.Add(res);
}
else if (!duplicates.Contains(res))
{
duplicates.Add(res);
}
}
foreach (char result in duplicates)
{
Console.WriteLine(result);
}
Console.ReadLine();
string is an array of chars. So, you can use your collection approach.
But, I would reccomend typed HashSet. Just load it with string and you'll get array of chars without duplicates, with preserved order.
take a look:
string s = "aaabbcdaaee";
HashSet<char> hash = new HashSet<char>(s);
HashSet<char> hashDup = new HashSet<char>();
foreach (var c in s)
if (hash.Contains(c))
hash.Remove(c);
else
hashDup.Add(c);
foreach (var x in hashDup)
Console.WriteLine(x);
Console.ReadKey();
Instead of a List<> i'd use a HashSet<> because it doesn't allow duplicates and Add returns false in that case. It's more efficient. I'd also use a Dictionary<TKey,Tvalue> instead of the list to track the count of each char:
string text = "elements";
var duplicates = new HashSet<char>();
var duplicateCounts = new Dictionary<char, int>();
foreach (char c in text)
{
int charCount = 0;
bool isDuplicate = duplicateCounts.TryGetValue(c, out charCount);
duplicateCounts[c] = ++charCount;
if (isDuplicate)
duplicates.Add(c);
}
Now you have all unique duplicate chars in the HashSet and the count of each unique char in the dictionary. In this example the set only contains e because it's three times in the string.
So you could output it in the following way:
foreach(char dup in duplicates)
Console.WriteLine("Duplicate char {0} appears {1} times in the text."
, dup
, duplicateCounts[dup]);
For what it's worth, here's a LINQ one-liner which also creates a Dictionary that only contains the duplicate chars and their count:
Dictionary<char, int> duplicateCounts = text
.GroupBy(c => c)
.Where(g => g.Count() > 1)
.ToDictionary(g => g.Key, g => g.Count());
I've shown it as second approach because you should first understand the standard way.
string name = "this is a a program program";
var arr = name.Split(' ').ToArray();
var dup = arr.Where(p => arr.Count(q => q == p) > 1).Select(p => p);
HashSet<string> hash = new HashSet<string>(dup);
string duplicate = string.Join(" ", hash);
You can do this through `LINQ
string name = "this is a a program program";
var d = name.Split(' ').GroupBy(x => x).Select(y => new { word = y.Key, Wordcount = y.Count() }).Where(z=>z.cou > 1).ToList();
Use LINQ to group values:
public static IEnumerable<T> GetDuplicates<T>(this IEnumerable<T> list)
{
return list.GroupBy(item => item).SelectMany(group => group.Skip(1));
}
public static bool HasDuplicates<T>(this IEnumerable<T> list)
{
return list.GetDuplicates().IsNotEmpty();
}
Then you use these extensions like this:
var list = new List<string> { "a", "b", "b", "c" };
var duplicatedValues = list.GetDuplicates();

How to sort list<string> in custom order

Having a string like "CAATCCAAC" I am generating all kmers from it (k is variable but has to be less than string) doing:
string dna = "CAATCCAAC";
dna = dna.Replace("\n", "");
int k = 5;
List<string> kmerList = new List<string>();
var r = new Regex(#"(.{" + k + #"})");
while (dna.Length >= k)
{
Match m = r.Match(dna);
//Console.WriteLine(m.ToString());
kmerList.Add(m.ToString());
dna = dna.Substring(1);
}
var sortedList = kmerList.OrderBy(i =>'A').
ThenBy(i => 'C').
ThenBy(i => 'G').
ThenBy(i => 'T').ToList();
foreach (string result in sortedList)
{
Console.WriteLine(result);
}
I want to sort result
AATCC
ATCCA
CAATC
CCAAC
TCCAA
However I am getting
CAATC
AATCC
ATCCA
TCCAA
CCAAC
How can I sort elements so they are ordered first by 'A' then by 'C' then by 'G' and finally 'T' ?
I tried
var sortedList = kmerList.OrderBy(i =>'A').
ThenBy(i => 'C').
ThenBy(i => 'G').
ThenBy(i => 'T').ToList();
but that wouldn't work
I want the result like to be aplied for all string like
AAAA
AACG
ACCC
ACCG
ACCT
...
TTTT
In order to sort a list in an alphabetical order,you should use the built-in Sort function:
kmerList.Sort();
If you want to order in alphabetical order you can use:
List<string> sorted = kmerList.OrderBy(x => x).ToList();
To get the reverse:
List<string> sorted = kmerList.OrderByDescending(x => x).ToList();
There's a build-in sort function. Try kmerList.Sort()

Using LINQ how to split string (not on character but on index)

I wanted to split a string
Input :
ABCDEFGHI
Output :
ABC, DEF, GHI
One way is by using For Loop.
string str = "ABCDEFGHI";
List<string> lst = new List<string>();
string temp = "";
for(int i = 0; i < str.Length; i++)
{
temp = str[i].Tostring();
if((i + 1) % 3 == 0)
{
lst.Add(temp);
temp = "";
}
}
string final_str = string.Join(", ", lst);
But how to do that using LINQ?
And another one (without MoreLinq):
var str = "ABCDEFGHI";
var tmp = str.Select((i, index) => new { i, index })
.GroupBy(g => g.index / 3, e => e.i)
.Select(g => String.Join("", g));
var final_string = String.Join(", ", tmp);
With the help of MoreLinq
List<string> lst = str.Batch(3).Select(s => String.Join("",s)).ToList();
using MoreLinq.Batch
var result = str.Batch(3);
type of result is IEnumerable>, ToArray can be used to make it IEnumerable< char[] >
EDIT I forgot last join statement in the first glance
var finalStr = String.Join(",",str.Batch(3).Select(x=>new String(x.ToArray())))
var str = "ABCDEFGHI";
var result = testStr.Select(s => testStr.IndexOf(s))
.Where(i => i%3 == 0)
.Select(i => testStr.Substring(i,3))
.Aggregate("", (a,s) => a += s + ",");
String.Join("", str.Select((x, i) => (i + 1)%3 == 0 ? x + " " : x.ToString()))

Categories