Array Question. Any ideas on how to solve my problem? - c#

I have around 1000 array elements. The elements consist of 1 user ID per element.
What I would like to do is shorten this array so each element contains 10 user ID's per element and each user ID per element is delimited by a comma.
Current array:
324234
2342234
0983242
....
New Array:
324234,2342342,234234234,234234,5436436,457456,456456,234234,234234,546456436
34234,23423426,54645654,34532423,23423432,4634634,2342342,234234,264353,345345
....
You may be asking WHY DO THAT?!
Well, I am sending the ID's to a post request. The request accepts either 1 ID or more. To shorten the number of requests I would like to send along 10 ID's per request.
Any ideas on how to group the old array into the new shorter array?

Then why don't you send them all once as a CSV ?
Later edit:
Note: code not tested
int amountPerCall = 10;
List<string> ids = new ArrayList<string>();
// add ids...
for (int i = 0 ; i < ids.Count; i += amountPerCall) {
Send(String.Join(",", ids, i, amountPerCall));
}

You could use MoreLINQ's Batch method:
IEnumerable<string> batches = input.Batch(10, ids => string.Join(",", ids));
If you don't want to use MoreLINQ itself, you can just look at the code to get an idea for what it does.
(Depending on which version of .NET you're using, you may need to convert the input to string.Join into an array. .NET 4 has introduced some helpful new overloads to that method.)

Related

List<object> Remove objects past a certain index (and Speed for doing so)

I am storing a bunch of url's in a list, There is expected to be many (around 3,000,000 at the most, more commonly around 50,000 to 200,000).
For an example of what I need to do:
ListOfStrings
[0]www.google.ca
[1]www.yahoo.com
[2]www.wikipedia.com
[3]www.youtube.com
[4]www.gmail.com
[5]www.stackoverflow.com
[6]www.steam.com
[7]www.microsoft.com
[8]www.ebay.com
I need to remove everything past string[5]. Should I just create a loop that does
while (ListOfStrings.Count>5)
{
ListOfStrings[6].Remove
}
Or is there faster method of doing this? (I was thinking possibly using .GetRange(0, ListOfStrings.IndexOf()) however there will be a maximum of 25 strings that need to be removed, so I'm not sure which one would be more efficient)
I am Also going to need to do the reverse (everything before Entry [5]) only I will need to remove many more of the strings, rather then 25 max. It will be more like 50,000 removals.
As I mentioned in comments:
If you want to don't touch the list and just want to take a subset:
If you want to take a subset from beginning of the list , you can use Take method:
var result= list.Take(5).ToList(); //The result is first 5 items
If you want to take a subset from middle of list, you can use Skip and Take methods:
var result = list.Skip(3).Take(5).ToList(); //the result is item 4 to 8
If you want to remove items from the list:
You can use RemoveRange:
list.RemoveRange(5, 4); //it changes list and removes all items above 5
Why not use Enumerable.Take()?
var result = list.Take(5);

What is an elegant way to find min value in a subset of an array?

I have an array a of 100 integers. What is a recommended way to find the min value in a[3] through a[70] AND the index of this min value? Assuming no duplication of values.
I know the clumsy way of looping through the relevant range of indices:
for(i = 3; i < 70, i++)
{
...
}
I am looking for a more elegant way of doing this in C# instead of looping. Thanks.
To Find out min
List<int> templist = a.Skip(3).Take(67).ToList();
int minimum = templist.Min();
For Index
int index = templist.FindIndex(i => i == minimum) + 3;
I added 3 because index in list will be 3 less than index in original sequence a.
What it is doing
Skip - Leaves first 3 values i.e. index 0,1,2 and returns remaining array.
Take - From the array returned by Skip it takes 67 values. (Since your for loop goes till starts from 3 and goes till 70 so you are basically looping on 67 items bcoz 70 - 3 = 67).
ToList - Converts returned sequence to List for finding index.
Min - Gets minimum from of it.
You have to use loop since it is a sequence. Since you said elegant so instead of for loop I used LINQ (Even it does that looping also).
If your data structure is not sorted then there is no way to do it without looping through all the elements in the sublist, either if you use some implicit looping through the provided API.
You cannot use a sorted collection since you are working on a subpart of it (so you'd need to create a sorted collection for the part of the list just for it), so in any case you'll have to loop over it.
LINQ's Aggregate is not the easiest, but it is arguably the least inefficient of the "elegant" solutions (though they're still more lines of code than the straightforward loop. Additionally, iterating through yourself is still the best because you are not allocating any additional memory).
But anyway, should you feel the need to make your successor hang you in effigy, you can do this instead of a straightforward loop:
var minValueAndItsIndex = a
.Skip(3)
.Take(70 - 3)
.Select((value, index) => new { Value = value, Index = index + 3})
.Aggregate((tuple1, tuple2) => (tuple1.Value < tuple2.Value) ? tuple1 : tuple2);
If you create a 2-item ValueType-based tuple and use that instead of the anonymous type, it will be comparable to the more-efficient direct iteration because it won't allocate any additional memory.

Convert comma separated twitter user-ids to corresponding screen names

I am developing a twitter application. The Twitter Followers API will return 5000 user-ids at a time as comma separated string. I need to pull the screen-name, followers count and following count from userlookup API. But this API will pull user details of 100 ids at a time.
Can anybody please help me in finding the most efficient/recommended way of breaking the comma separated string to batches of 100 userids and getting the user details?
Here is what you can do, split happens only once.
string ids = "YOUR IDs";
int limit = 100;
List<string[]> store = new List<string[]>();
var split = ids.Split(',');
int counter = 0;
while (true) {
var batch = string.Join(",", split.Skip(counter++ * limit).Take(limit));
if (string.IsNullOrEmpty(batch)) break;
//Make your call here
}
I would use result.Split(",").Take(100) this will split the whole thing into an array and then take the top 100 results. If this doesnt perform fast enough you should manually stream the string to only read the first 100 commas. This will be slightly faster but not as syntactically elegant. In the first case you should still be able to process 5000 comma separated elements in a fraction of a second on any modern machine.

break up array into little arrays

i am sending out email to a list of people. I have the list of recipients in array but the list can get up to 500 people. There is a limitation on the number of recipients that my mail server sends out at once (50 recipients)
so if the list is > 50 i need to break it up in to different mails.
What is the best way to take one array and break it up into arrays of 50
for example:
if array is 120 long, i would expect 3 arrays returned, one with 50, another with 50 and a third with 20.
You could use the Batch operation from MoreLINQ:
Person[] array = ...;
var arrays = list.Batch(50).Select(x = x.ToArray());
foreach (Person[] shorterArray in arrays)
{
...
}
(If you're happy with IEnumerable<Person> instead of arrays, you don't need the Select call of course.)
Maybe ArraySegment<T> works for you? You'd have to split it up manually though, but this is not hard in a loop.
int recipient = 0;
while (recipient < recipients.Count) {
ArraySegment<string> recipientSegment = new ArraySegment<string>(recipients, recipient, Math.Min(50, recipients.Count-recipient));
// build your message here, using the recipientSegment for the names
recipient += 50;
}
I would simply iterate over the complete array, building up the recipients string, then sending out an email when the limit is reached, then resetting the string and continuing on with the iteration until the next limit event or until the end of the array is reached.
If you can use LINQ when you may find this useful: Linq: How to group by maximum number of items
Shouldn't LINQ be the right stuff for this?
A common method for "paging" results from a set is to combine the Skip and Take methods provided by LINQ. This solution is great because it can be further combined with other LINQ methods to implement filtering, ordering, etc. as needed.
I'm not sure what the performance considerations are for your application, so keep in mind that this may not perform very well for sets where the number of pages is relatively large (i.e., batch size is significantly smaller than the total size of the set), but it's at least fairly straightforward for anyone familiar with this style of coding.
Here's an example of what this implementation might look like:
List<EmailAddress> list = new List<EmailAddress>();
const int BATCH_SIZE = 50;
for (int i = 0; i < list.Count; i += BATCH_SIZE)
{
IEnumerable<EmailAddress> currentBatch =
list.Skip(i).Take(BATCH_SIZE);
// do stuff...
}

Array of an unknown length in C#

I've just started learning C# and in the introduction to arrays they showed how to establish a variable as an array but is seems that one must specify the length of the array at assignment, so what if I don't know the length of the array?
Arrays must be assigned a length. To allow for any number of elements, use the List class.
For example:
List<int> myInts = new List<int>();
myInts.Add(5);
myInts.Add(10);
myInts.Add(11);
myInts.Count // = 3
Use List<> to build up an 'array' of unknown length.
Use List<>.ToArray() to return a real array, and not a List.
var list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
var array = list.ToArray();
A little background information:
As said, if you want to have a dynamic collection of things, use a List<T>. Internally, a List uses an array for storage too. That array has a fixed size just like any other array. Once an array is declared as having a size, it doesn't change. When you add an item to a List, it's added to the array. Initially, the List starts out with an array that I believe has a length of 16. When you try to add the 17th item to the List, what happens is that a new array is allocated, that's (I think) twice the size of the old one, so 32 items. Then the content of the old array is copied into the new array. So while a List may appear dynamic to the outside observer, internally it has to comply to the rules as well.
And as you might have guessed, the copying and allocation of the arrays isn't free so one should aim to have as few of those as possible and to do that you can specify (in the constructor of List) an initial size of the array, which in a perfect scenario is just big enough to hold everything you want. However, this is micro-optimization and it's unlikely it will ever matter to you, but it's always nice to know what you're actually doing.
You can create an array with the size set to a variable, i.e.
int size = 50;
string[] words = new string[size]; // contains 50 strings
However, that size can't change later on, if you decide you need 100 words. If you need the size to be really dynamic, you'll need to use a different sort of data structure. Try List.
Use an ArrayList if in .NET 1.x, or a List<yourtype> if in .NET 2.0 or 3.x.
Search for them in System.Collections and System.Collections.Generics.
You might also want to look into Dictionarys if your data is unique, This will give you two columns to work with.
User name , Total bill
it gives you a lot of built in tools to search and update just the value.
var yummy = new List<string>();
while(person.FeelsHappy()) {
yummy.Add(person.GetNewFavoriteFood());
}
Console.WriteLine("Sweet! I have a list of size {0}.", list.Count);
Console.WriteLine("I didn't even need to know how big to make it " +
"until I finished making it!");
try a generic list instead of array
In a nutshell, please use Collections and Generics.
It's a must for any C# developer, it's worth spending time to learn :)
As detailed above, the generic List<> is the best way of doing it.
If you're stuck in .NET 1.*, then you will have to use the ArrayList class instead. This does not have compile-time type checking and you also have to add casting - messy.
Successive versions have also implemented various variations - including thread safe variants.
If you really need to use an array instead of a list, then you can create an array whose size is calculated at run time like so...
e.g i want a two dimensional array of size n by n. n will be gotten at run time from the user
int n = 0;
bool isInteger = int.TryParse(Console.ReadLine(), out n);
var x = new int[n,n];

Categories

Resources