c#


Shift elements in string array to left to fill 'holes'


I have a list of names and phone numbers like so:
var phonelist = List<string[]>
{
new string[] {"Bill", "1234", "12345", "12314" },
new string[] {"Bob", "", "12345", "12314" },
new string[] {"Chris", "", "", "12314" },
new string[] {"Dave", "1234", "", "12314" },
new string[] {"Andy", "1234", "12345", "" },
}
What is the most efficient/elegant way to process this list so that the 'empty' numbers get filled from the right ?
Note, the arrays should stay the same length, like so:
var phonelist = List<string[]>
{
new string[] {"Bill", "1234", "12345", "12314" },
new string[] {"Bob", "12345", "12314", "" },
new string[] {"Chris", "12314", "", "" },
new string[] {"Dave", "1234", "12314", "" },
new string[] {"Andy", "1234", "12345", "" },
}
for each array cell, check if its empty and swap it with cell+1, if it's still empty swap it with cell+2.. when cell becomes not empty do the same thing with cell+2...
int j;
foreach (string[] strs in phoneList)
{
for (int i = 0; i < strs.Length; i++)
{
j = 1;
while (string.IsNullOrEmpty(strs[i]) && j < strs.Length - i)
{
if (!string.IsNullOrEmpty(strs[i + j])) // to not swap 2 empty strings
{
strs[i] = strs[i + j];
strs[i + j] = "";
}
j++;
}
}
}
public static void PutEmptyStringsToTheEnd(string[] array) {
int j = 0;
for (int i = 0; i < array.Length; ++i)
if (array[i].Length > 0)
array[j++] = array[i];
while (j < array.Length)
array[j++] = "";
}
Call this function for each List element.
simple and ugly :(
for(var x=0;x<phonelist.Count;x++)
{
var strings = phonelist[x];
var l = strings.Length;
var newAr=new string[l];
var k = 0;
for (var i = 0; i < l; )
{
if(strings[i]!="")
{
newAr[k++] = strings[i];
}
i++;
}
for (; k < l; k++)
newAr[k] = "";
phonelist[x] = newAr;
}
You could do something like that :
Comparison<string> comparison = (x,y) =>
{
if (String.IsNullOrEmpty(x))
return 1;
if (String.IsNullOrEmpty(y))
return -1;
return String.Compare(x,y);
}
foreach (string[] array in phoneList)
{
Array.Sort(array, comparison);
}
However you will need to tune the comparison logic a bit to keep the names before the numbers
EDIT : since the name seems to always be the first element, another option is to exclude it from the sort. No Array.Sort overload takes a Comparison<T> and a range, so you have to use a IComparer<T> instead :
class MyComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (String.IsNullOrEmpty(x))
return 1;
if (String.IsNullOrEmpty(y))
return -1;
return String.Compare(x,y);
}
}
foreach (string[] array in phonelist)
{
Array.Sort(array, 1, array.Length - 1, new MyComparer());
}
This should work. I'm not that knownledged at C#, but the idea is there
foreach(string[] person in phonelist)
{
string[] newPerson = {"","","",""};
int index = 0;
for(int i=0; i<4; i++)
{
if(!String.IsNullOrEmpty(person[i])) newPerson[index++] = person[i];
}
person = newPerson;
}
This is cooler
List<string[]> result = phonelist.Select(per => per.OrderBy(txt=>txt.Length==0).ToArray()).ToList();
List<string[]> sorted = new List<string[]>();
foreach (string[] entry in phoneList)
{
List<string> nonEmpty = (from s in entry
where String.IsNullOrEmpty(s) == false
select s).ToList();
int pad = entry.Length - nonEmpty.Count;
List<string> pads = new List<string>();
while (pad > 0)
{
pads.Add(String.Empty);
--pad;
}
List<string> sortedEntry = new List<string>();
sortedEntry.AddRange(nonEmpty);
sortedEntry.AddRange(pads);
sorted.Add(sortedEntry.ToArray());
}

Related Links

How to Ignore the list if values are empty in c#
Why is Async Void so bad? [duplicate]
One ViewModel two Views with MVVMLight in WPF
Find n-level nested SubDocument MongoDB
Open asp LinkButton in a new tab
Creating a Font using Floating Point Size returns incorrect Sized Font
System.Web.HttpUtility.HtmlDecode giving different results
C# binding datagridviewcomboboxcolumn to list display, formatting, preferred Size error
How to design my online Game Server for Unity3d?
Decrypt C#-encrypted data in C++ using Windows AES crypto provider
What is the replacement of CryptoConfig class in .NETCore?
C# Service Reference error: A child element named 'element' with same key already exists
How to remove broken background of ListViewItem In UWP?
SelectIndexChange code behind from a different nameSpace
C#: Optimize conditional within a loop
Post JSON object array to a Web API

Categories

HOME
excel-formula
teradata
primefaces
ide
intellij-idea
python-requests
c++builder
skypedeveloper
coordinates
opc-ua
overrides
symfony-sonata
jshell
gnuradio
qt4
ethereum
dynamics-crm-2011
drush
cakephp-2.0
react-select
ajaxcontroltoolkit
polybase
opengraph
ps
pydub
stack-trace
workflow-foundation
launchd
request-uri
ocl
textview
exacttarget
wercker
imdb
offset
pymunk
ponylang
mongoid5
dotnetnuke-module
stdin
azure-web-roles
delphi-xe
grails-2.0
bootstrap-carousel
gradlew
taleo
encoder
automapper-4
g77
confluent
petapoco
was
lightspeed
directinput
x12
system-integration
avi
jersey-test-framework
bioconductor
transbase
cloud-storage
bootstrap-tabs
consul-template
stereotype
photogrammetry
firebase-tools
dockerpy
backtrace
nsq
cordova-3
jsonmodel
fxmlloader
os.walk
worklight-appcenter
msdropdown
flask-mongoengine
boofcv
mdp
adabas
dylan
maven-webstart-plugin
select2-rails
mysql2
feincms
invalidoperationexception
google-email-audit-api
bash4
fileoutputstream
digg
opendir
jexcelapi
designated-initializer
coderush-xpress
ihtmldocument2
user-preferences
content-delivery-network
managed-code
stackless

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App