split List<User> in multiple List<User> in c# - list

I want to split List of user generic List into its small list with each 5 records.
Ex
I have List: u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15.
so must be split into
List1:u1,u2,u3,u4,u5
List2:u6,u7,u8,u9,u10
List3:u11,u12,u13,u14,u15
Any direct method available or need programing logic in c# ?

You can group on the index:
List<List<User>> lists =
list
.Select((u, i) => new { List = i / 5, User = u })
.GroupBy(g => g.List, g => g.User)
.Select(g => g.ToList())
.ToList();
You can also use Range to make a loop and get a part of the list for each iteration:
List<List<User>> lists =
Enumerable.Range(0, (list.Count + 4) / 5)
.Select(n => list.Skip(n * 5).Take(5).ToList())
.ToList();

You can Use Skip(count) and Take(count) methods.

// These are your objects, put here your init code
var list = Enumerable.Range(1, 20).ToList();
var lists = new List<int>[(list.Count + 4) / 5]; // The array of lists you wanted
for (int i = 0; i < lists.Length; i++)
{
lists[i] = list.Skip(i * 5).Take(5).ToList();
}
The (list.Count + 4) / 5 is a method to round UP the division (if I have 6 elements in list, I want two sublists)
If you really need a List of List...
var lists = new List<List<int>>((list.Count + 4) / 5);
for (int i = 0; i < lists.Capacity; i++)
{
lists.Add(list.Skip(i * 5).Take(5).ToList());
}

I think this might be more efficient since you're not doing groupings, orderings and such. This is just a single iteration over the dataset.
var splitList= new List<IEnumerable<User>>();
List<User> currentList = null;
int count = 0;
foreach(var user in users)
{
if (0 == count% 5)
{
currentList = new List<User>(5);
returnValue.Add(currentList);
}
currentList.Add(key);
count++;
}
return returnValue;

Related

Kotlin a list of random distinct numbers

I am creating a list of random numbers using the following approach
val randomList = List(4) { Random.nextInt(0, 100) }
However, this approach doesn't work as I want to avoid repetitions
One way is to shuffle a Range and take as many items as you want:
val randomList = (0..99).shuffled().take(4)
This is not so efficient if the range is big and you only need just a few numbers.In this case it's better to use a Set like this:
val s: MutableSet<Int> = mutableSetOf()
while (s.size < 4) { s.add((0..99).random()) }
val randomList = s.toList()
Create:
val list = (0 until 100).toMutableList()
val randList = mutableListOf<Int>()
for (i in 0 until 4) {
val uniqueRand = list.random()
randList.add(uniqueRand)
list.remove(uniqueRand)
}
One line approach to get a list of n distinct random elements. Random is not limited in any way.
val list = mutableSetOf<Int>().let { while (it.size() < n) it += Random.nextInt(0, 100) }.toList()

Check items from a List of ValueTuple and return results in another List of ValueTuple C#7

Please consider the following list of ValueTuple C#7
static void Main(string[] args)
{
List<(double prices, int matches)> myList = new List<(double, int)>();
myList.Add((100, 10));
myList.Add((100.50 , 12));
myList.Add((101 , 14));
myList.Add((101.50 , 16));
}
What would be a simple way to search for items meeting conditions for "prices" AND "matches" within the List and return the results in another List of ValueTuple.
For instance if I want to return another List of ValueTuples meeting "prices > 101 and matches > 6"
Can you post an example please?
It's easier if you give names to the items :
var myList = new List<(double d,int i)>
{
(100, 10),
(100.50 , 12),
(101 , 14),
(101.50 , 16)
};
var results = myList.Where(x => x.d>101 && x.i>6);
Without the names you'd have to write
var results = myList.Where(x => x.Item1>101 && x.Item2>6);
C# 7.3 added tuple equality but not comparison. You can now write :
var result = myList.Where(d=>d == (101,14));
and
var result = myList.Where(d=>d != (101,14));
But not
var result = myList.Where(d=>d > (101,14));

Making groups (combinations) of objects using their min/max values

First of all, this is my first question, you can tell me how to improve it and what tags to use.
What I am trying to do is I have a bunch of objects that have minimal and maximal values by those values you can deduce if two objects have some sort of overlapping value and thus they can be put together in a group
This question might need dynamic programming to solve.
example objects:
1 ( min: 0, max: 2 )
2 ( min: 1, max: 3 )
3 ( min: 2, max: 4 )
4 ( min: 3, max: 5 )
object 1 can be grouped with objects 2, 3
object 2 can be grouped with objects 1, 3, 4
object 3 can be grouped with objects 1, 2, 4
object 4 can be grouped with objects 2, 3
as you can see there are multiple ways to group those elements
[1, 2]
[3, 4]
[1]
[2, 3]
[4]
[1]
[2, 3, 4]
[1, 2, 3]
[4]
now there should be some sort of rule to deduce which of the solutions is the best solution
for example least amount of groups
[1, 2]
[3, 4]
or
[1]
[2, 3, 4]
or
[1, 2, 3]
[4]
or most objects in one group
[1]
[2, 3, 4]
or
[1, 2, 3]
[4]
or any other rule that uses another attribute of said objects to compare the solutions
what I have now:
$objects = [...objects...];
$numberOfObjects = count($objects);
$groups = [];
for ($i = 0; $i < $numberOfObjects; $i++) {
$MinA = $objects[$i]['min'];
$MaxA = $objects[$i]['max'];
$groups[$i] = [$i];
for ($j = $i + 1; $j < $numberOfObjects; $j++) {
$MinB = $objects[$j]['min'];
$MaxB = $objects[$j]['max'];
if (($MinA >= $MinB && $MinA <= $MaxB) || ($MaxA >= $MinB && $MaxA <= $MaxB) || ($MinB >= $MinA && $MinB <= $MaxA)) {
array_push($groups[$i], $j);
}
}
}
this basically creates an array with indexes of objects that can be grouped together
from this point, I don't know how to proceed, how to generate all the solution and then check each of them how good it is, and the pick the best one
or maybe there is even better solution that doesn't use any of this?
PHP solutions are preferred, although this problem is not PHP-specific
When I was first looking at your algorithm, I was impressed by how efficient it is :)
Here it is rewritten in javascript, because I moved away from perl a good while ago:
function setsOf(objects){
numberOfObjects = objects.length
groups = []
let i
for (i = 0; i < numberOfObjects; i++) {
MinA = objects[i]['min']
MaxA = objects[i]['max']
groups[i] = [i]
for (j = i + 1; j < numberOfObjects; j++) {
MinB = objects[j]['min']
MaxB = objects[j]['max']
if ((MinA >= MinB && MinA <= MaxB) || (MaxA >= MinB && MaxA <= MaxB) ||
(MinB >= MinA && MinB <= MaxA)) {
groups[i].push(j)
}
}
}
return groups
}
if you happen to also think well in javascript, you might find this form more direct (it is identical, however):
function setsOf(objects){
let groups = []
objects.forEach((left,i) => {
groups[i]=[i]
Array.from(objects).splice(i+1).forEach((right, j) => {
if ((left.min >= right.min && left.min <= right.max) ||
(left.max >=right.max && left.max <= right.max) ||
(right.min >= left.min && right.min <= left.max))
groups[i].push(j+i+1)
})
})
return groups
}
so if we run it, we get:
a = setsOf([{min:0, max:2}, {min:1, max:3}, {min:2, max:4}, {min:3, max: 5}])
[Array(3), Array(3), Array(2), Array(1)]0: Array(3)1: Array(3)2: Array(2)3: Array(1)length: 4__proto__: Array(0)
JSON.stringify(a)
"[[0,1,2],[1,2,3],[2,3],[3]]"
and it does impressively catch the compound groups :) a weakness is that it is capturing groups containing more objects than necessary, without capturing all available objects. You seem to have a very custom selection criteria. To me, it seems like the groups should either be every last intersecting subset, or only subsets where each element in the group provides unique coverage: [0,1], [0,2], [1,2], [1,3], [2,3], [0,1,3]
the algorithm for that is perhaps more involved. this was my approach, and it is nowhere near as terse and elegant as yours, but it works:
function intersectingGroups (mmvs) {
const min = []
const max = []
const muxo = [...mmvs]
mmvs.forEach(byMin => {
mmvs.forEach(byMax => {
if (byMin.min === byMax.min && byMin.max === byMax.max) {
console.log('rejecting identity', byMin, byMax)
return // identity
}
if (byMax.min > byMin.max) {
console.log('rejecting non-overlapping objects', byMin, byMax)
return // non-overlapping objects
}
if ((byMax.max <= byMin.max) || (byMin.min >= byMax.min)) {
console.log('rejecting non-expansive coverage or inversed order',
byMin, byMax)
return // non-expansive coverage or inversed order
}
const entity = {min: byMin.min, max: byMax.max,
compositeOf: [byMin, byMax]}
if(muxo.some(mv => mv.min === entity.min && mv.max === entity.max))
return // enforcing Set
muxo.push(entity)
console.log('adding', byMin, byMax, muxo)
})
})
if(muxo.length === mmvs.length) {
return muxo.filter(m => 'compositeOf' in m)
// solution
} else {
return intersectingGroups(muxo)
}
}
now there should be some sort of rule to deduce which of the solutions is the best solution
Yeah, so, usually for puzzles or for a specification you are fulfilling, that would be given as part of the problem. As it is, you want a general method that is adaptable. It's probably best to make an object that can be configured with the results and accepts rules, then load the rules you are interested in, and the results from the search, and see what rules match where. For example, using your algorithm and sample criteria:
least amount of groups
start with code like:
let reviewerFactory = {
getReviewer (specification) { // generate a reviewer
return {
matches: [], // place to load sets to
criteria: specification,
review (objects) { // review the sets already loaded
let group
let results = {}
this.matches.forEach(mset => {
group = [] // gather each object from the initial set for each match in the result set
mset.forEach(m => {
group.push(objects[m])
})
results[mset] = this.criteria.scoring(group) // score the match relative to the specification
})
return this.criteria.evaluation(results) // pick the best score
}
}
},
specifications: {}
}
now you can add specifications like this one for least amount of groups:
reviewerFactory.specifications['LEAST GROUPS'] = {
scoring: function (set) { return set.length },
evaluation: function (res) { return Object.keys(res).sort((a,b) => res[a] - res[b])[0] }
}
then you can use that in the evaluation of a set:
mySet = [{min:0, max:2}, {min:1, max:3}, {min:2, max:4}, {min:3, max: 5}]
rf = reviewerFactory.getReviewer(reviewerFactory.specifications['LEAST GROUPS'])
Object {matches: Array(0), criteria: Object, review: function}
rf.matches = setsOf(mySet)
[Array(3), Array(3), Array(2), Array(1)]
rf.review(mySet)
"3"
or, most objects:
reviewerFactory.specifications['MOST GROUPS'] = {
scoring: function (set) { return set.length },
evaluation: function (res) { return Object.keys(res).sort((a,b) => res[a] - res[b]).reverse()[0] }
}
mySet = [{min:0, max:2}, {min:1, max:3}, {min:2, max:4}, {min:3, max: 5}]
reviewer = reviewerFactory.getReviewer(reviewerFactory.specifications['MOST GROUPS'])
reviewer.matches = setsOf(mySet)
reviewer.review(mySet)
"1,2,3"
Of course this is arbitrary, but so are the criteria, by definition in the OP. Likewise, you would have to change the algorithms here to work with my intersectingGroups function because it doesn't return indices. But this is what you are looking for I believe.

How do I create a list with no predefined length and assigned values to their positions, in Dart?

I'm developing my first application with Dart, which had previously created in JavaScript.
In my statement in JavaScript I have declared a List, and I assign values ​​to the first three positions, as seen here:
serpF var = new List ();
serpF [0] = 10;
serpF [1] = 10;
serpF [2] = 10;
How I can do the same in Dart? I have read the documentation of Lists and Arrays of Seth Ladd in "http://blog.sethladd.com/2011/12/lists-and-arrays-in-dart.html" and I've tried everything, but it is being impossible.
The javaScript code does not work in Dart because it is an error to access past the end of the List. Dart is like many other languages as this is a way to catch logic errors.
What you can do is add elements to a List:
var serpF = new List(); // This list has length == 0.
serpF.add(10);
serpF.add(10);
serpF.add(10);
You can use method cascades to shorten the code:
var serfP = [];
serpF..add(10)..add(10)..add(10);
If you do know the length, you might also try one of the other List constructors:
var serfP = new List.filled(3, 10);
var serfP = new List.generate(3, (i) => 10);
I addition to what Stephen suggests you can also do:
var serpF = [10, 10, 10];
or
var serpF = new List();
serpF.length = 3;
serpF[0] = 10;
serpF[1] = 10;
serpF[2] = 10;
You can also use the List.generate() constructor:
var list = new List.generate(3, (_) => 10, growable: true);
print(list); // Prints [10, 10, 10].
The first arg specifies the number of elements in the list, the second arg takes a callback to give each element a value, and the third arg ensures that the list is not fixed-width.

List.shuffle() in Dart?

I'm looking every where on the web (dart website, stackoverflow, forums, etc), and I can't find my answer.
So there is my problem: I need to write a function, that print a random sort of a list, witch is provided as an argument. : In dart as well.
I try with maps, with Sets, with list ... I try the method with assert, with sort, I look at random method with Math on dart librabry ... nothing can do what I wana do.
Can some one help me with this?
Here some draft:
var element03 = query('#exercice03');
var uneliste03 = {'01':'Jean', '02':'Maximilien', '03':'Brigitte', '04':'Sonia', '05':'Jean-Pierre', '06':'Sandra'};
var alluneliste03 = new Map.from(uneliste03);
assert(uneliste03 != alluneliste03);
print(alluneliste03);
var ingredients = new Set();
ingredients.addAll(['Jean', 'Maximilien', 'Brigitte', 'Sonia', 'Jean-Pierre', 'Sandra']);
var alluneliste03 = new Map.from(ingredients);
assert(ingredients != alluneliste03);
//assert(ingredients.length == 4);
print(ingredients);
var fruits = <String>['bananas', 'apples', 'oranges'];
fruits.sort();
print(fruits);
There is a shuffle method in the List class. The methods shuffles the list in place. You can call it without an argument or provide a random number generator instance:
var list = ['a', 'b', 'c', 'd'];
list.shuffle();
print('$list');
The collection package comes with a shuffle function/extension that also supports specifying a sub range to shuffle:
void shuffle (
List list,
[int start = 0,
int end]
)
Here is a basic shuffle function. Note that the resulting shuffle is not cryptographically strong. It uses Dart's Random class, which produces pseudorandom data not suitable for cryptographic use.
import 'dart:math';
List shuffle(List items) {
var random = new Random();
// Go through all elements.
for (var i = items.length - 1; i > 0; i--) {
// Pick a pseudorandom number according to the list length
var n = random.nextInt(i + 1);
var temp = items[i];
items[i] = items[n];
items[n] = temp;
}
return items;
}
main() {
var items = ['foo', 'bar', 'baz', 'qux'];
print(shuffle(items));
}
You can use shuffle() with 2 dots like Vinoth Vino said.
List cities = ["Ankara","London","Paris"];
List mixed = cities..shuffle();
print(mixed);
// [London, Paris, Ankara]