Picking N unique random Enums in Dart - dart

How can I pick N unique random enums in dart?
enum Fruits { Apple, Peach, Orange, Mango }
List<Fruits> fruit = Fruits.random(N) // <-- implement this

you can create an extension for enum
enum Fruits { Apple, Peach, Orange, Mango }
extension FruitsExt on Fruits {
static List<Fruits> generateRandomFruits(int n) {
var rnd = Random();
return List.generate(n, (i) => Fruits.values[rnd.nextInt(Fruits.values.length)]);
}
static List<Fruits> generateRandomUniqueFruits(int n) {
var list = List<Fruits>.from(Fruits.values)..shuffle();
return list.take(n).toList();
}
}
and use it like this
List<Fruits> fruits = FruitsExt.generateRandomFruits(10);
List<Fruits> fruits = FruitsExt.generateRandomUniqueFruits(3);
or use it without extension
var rnd = Random();
var list = List.generate(10, (i) => Fruits.values[rnd.nextInt(Fruits.values.length)]);
or, as mentioned in comments below by #Irn
you can make them top level functions
List<Fruits> generateRandomFruits(int n) {
var rnd = Random();
return List.generate(n, (i) => Fruits.values[rnd.nextInt(Fruits.values.length)]);
}
List<Fruits> generateRandomUniqueFruits(int n) {
var list = List<Fruits>.from(Fruits.values)..shuffle();
return list.take(n).toList();
}

Some user's answers is indeed helping. But if we would consider your option of having only unique enums, then we might use some other approach. The approach is basically to use Set class to store only the unique data. And we are concerned about getting the final data as List(), then convert it using toList()
import 'dart:math';
enum Fruits { Apple, Peach, Orange, Mango }
void main() {
// we are initializing our Fruits to be a set to store UNIQUE DATA ONLY
Set<Fruits> _fruits = {};
// this will go on for the length of Fruits, which is 5 right now
for(int i=0; i<Fruits.values.length; i++){
// this will only generate the number till your enum's length
var index = Random().nextInt(Fruits.values.length);
_fruits.add(Fruits.values[index]);
}
// converting it to List finally
print(_fruits.toList());
}
OUTPUT
[Fruits.Apple, Fruits.Orange, Fruits.Peach]

You can get a list of all values from the enums.values, then shuffle the list and take an appropriate long sublist of it:
enum Fruits { Apple, Peach, Orange, Mango }
void main() {
List<Fruits> fruit = List.from(Fruits.values);
for(int i=0;i<3;++i) {
fruit.shuffle();
print(fruit.sublist(0,3));
}
}
Output:
[Fruits.Mango, Fruits.Orange, Fruits.Apple]
[Fruits.Apple, Fruits.Orange, Fruits.Mango]
[Fruits.Orange, Fruits.Apple, Fruits.Peach]

I solved it eventually with sets as #Alok suggested:
import 'dart:math';
List<T> generateRandomList<T>(int N, List<T> list) {
Set<T> setOfT = {};
var rnd = Random();
while (setOfT.length < N) {
setOfT.add(list[rnd.nextInt(list.length)]);
}
return setOfT.toList()..shuffle();
}
usage:
enum Fruits { Apple, Peach, Orange, Mango }
print(generateRandomList(2, Fruits.values));
output:
[Fruits.Peach, Fruits.Mango]

A general approach for picking a number of elements from any list (or iterable) uniformly at random would be:
import "dart:math";
extension<T> on Iterable<T> {
/// Chooses [count] of the elements of this iterable.
///
/// The elements are chosen at random, with each
/// element having an equal chance of being in the
/// resulting list.
/// The returned elements are not in any specific order.
List<T> choose(int count, [Random random]) {
var iterator = this.iterator;
List<T> result = [
for (var i = 0; i < count; i++)
if (iterator.moveNext())
iterator.current
else
throw StateError("Too few elements")
];
random ??= Random();
var seenCount = count;
while (iterator.moveNext()) {
seenCount++;
var pos = random.nextInt(seenCount);
if (pos < count) result[pos] = iterator.current;
}
return result;
}
}
You can then use it on enums as var someFruits = Fruites.values.choose(2);.

Related

How to input a list of data from console in dart?

In Dart I want to take input from user 100 data into a list from console. How can I do that?
void main() {
int value;
List<int> list = [0];
var largest = list[0];
for (var i = 0; i < list.length; i++) {
list.add(stdin.readByteSync());
if (list[i] > largest) {
largest = list[i];
}
}
print(largest);
}
After some dialog in the chat we ended up with the following solution:
import 'dart:io';
void main() {
// Create empty list
final list = <int>[];
// Number of numbers we want to take
const numbersWeWant = 100;
// Loop until we got all numbers
for (var i = 0; i < numbersWeWant; i++) {
int? input;
// This loop is for asking again if we get something we don't see as a number
do {
print('Input number nr. $i:');
// Get a number. input is going to be null if the input is not a number
input = int.tryParse(stdin.readLineSync() ?? '');
} while (input == null); // loop as long as we don't got a number
// Add the number we got to the list
list.add(input);
}
// Use list.reduce to find the biggest number in the list by reducing the
// list to a single value using the compare method.
print('Largest number: ${list.reduce((a, b) => a > b ? a : b)}');
}

How can I initialize a list filled with previous initialized lists?

The current code:
class A {
List<int> listOne = [];
List<int> listTwo = [];
List≤int> listOfLists = [
...listOne,
...listTwo
];
}
Results in the following error for each list with an spread operator (...):
error: The instance member 'listOne' can't be accessed in an initializer.
error: The instance member 'listTwo' can't be accessed in an initializer.
What I know:
listOne etc. can't be referenced in another initializer
So what I tried: https://dart.dev/tools/diagnostic-messages#implicit_this_reference_in_initializer
class C {
int x;
C() : x = defaultX;
static int get defaultX => 0;
}
Unfortunately, I do not know how to translate that to solve my problem.
Can you guys help me out?
You need to explicitly make a constructor and do the assignment there.
class A {
List<int> listOne = [];
List<int> listTwo = [];
List<int> listOfLists;
A() {
listOfLists = [...listOne, ...listTwo];
}
}
If you're using null-safety then you should add the late keyword.
class A {
List<int> listOne = [];
List<int> listTwo = [];
late List<int> listOfLists;
A() {
listOfLists = [...listOne, ...listTwo];
}
}

Dart converting String to Array then compare two array

I'm trying to convert strings to arrays then compare two arrays. If the same value needs to remove from both array. Then finally merge two arrays and find array length. Below is my code
String first_name = "siva";
String second_name = "lovee";
List<String> firstnameArray=new List();
List<String> secondnameArray=new List();
firstnameArray = first_name.split('');
secondnameArray = second_name.split('');
var totalcount=0;
for (int i = 0; i < first_name.length; i++) {
for (int j = 0; j < second_name.length; j++) {
if (firstnameArray[i] == secondnameArray[j]) {
print(firstnameArray[i] + "" + " == " + secondnameArray[j]);
firstnameArray.removeAt(i);
secondnameArray.removeAt(i);
break;
}
}
}
var finalList = new List.from(firstnameArray)..addAll(secondnameArray);
print(finalList);
print(finalList.length);
But always getting this error Unsupported operation: Cannot remove from a fixed-length list can you help me how to fix this issue. Thanks.
Seems like what you are trying to do is to find the length of unique characters in given two strings. Well, the Set type is perfect for this use-case. Here's an example of what you can do:
void main() {
String first = 'abigail';
String second = 'allie';
var unique = '$first$second'.split('').toSet();
print(unique);
}
This would give you an output of:
{a, b, i, g, l, e}
On which you may perform functions like .toList(), or .where() or .length.
You can ensure that firstnameArray, secondnameArray is not a fixed-length list by initializing it as below:
var firstnameArray = new List<String>.from(first_name.split(''));
var secondnameArray= new List<String>.from(second_name.split(''));
Thereby declaring firstnameArray, secondnameArray to be a mutable copy of input.

Dart - find most common character in a string

I'm stuck on this common interview question using Dart. I need to return the most common character in a given string. I'm trying to create a map with a count for each character as the first step.
This is my progress so far:
main(List<String> arguments) {
maxChar('hello');
}
void maxChar(String word) {
Map<String, int> charMap = {};
int max = 0;
String maxChar = '';
word.split('').forEach((char) {
if(charMap.containsValue(char)) {
charMap[char]+1;
return;
} else {
charMap[char] = 1;
}
});
print(charMap);
}
Right now its not even counting the correct amount of the letter 'l'. It's outputting:
{h: 1, e: 1, l: 1, o: 1}
What am I doing wrong? Is there an easier way to return the most common character in a String in Dart?
Thanks!
EDIT:
Ok, I've solved it, but surely there is a more concise way of solving this problem. See my solution below:
main(List<String> arguments) {
print(max_char.maxChar('hello'));
}
String maxChar(String word) {
Map<String, int> charMap = {};
int max = -1;
String maxChar = '';
word.split('').forEach((char) {
if(charMap.containsKey(char)) {
charMap[char]++;
return;
} else {
charMap[char] = 1;
}
});
charMap.forEach((k,v) {
if(v > max) {
max = v;
maxChar = k;
}
});
return maxChar;
}
A shorter approach to counting the characters is definitely possible:
String charCount(String chars) {
int maxChar = -1;
int maxCount = 0;
var counts = <int, int>{};
for (var char in chars.runes) {
int count = counts.update(char, (n) => n + 1, ifAbsent: () => 1);
if (count > maxCount) {
maxCount = count;
maxChar = char;
}
}
return String.fromCharCode(maxChar);
}
If you just want to count the characters, you can remove all the lines mentioning maxCount and maxChar.
I use integers to represent the characters instead of strings. That's cheaper and just as precise, and it allows you to recognize and combine Unicode UTF-16 surrogates.

Allocate/Deallocate dynamic array of struct pointers in C

say i have the following two struct definitions in C.
struct child {
int x;
};
struct Yoyo {
struct child **Kids;
};
How would i go about allocating the memory for Kids.
say for example i have some function Yoyo_create().
static struct Yoyo * yoyo_create() {
int n = 32000;
struct Yoyo *y;
y = malloc(sizeof( *Yoyo));
y->Kids = malloc(n*sizeof(*Child));
for (i = 0 ; i < n ; i ++) { y->Kids[i] = NULL; }
}
and then to destroy the Kids in some "destructor function" i would do.
void yoyo_destroy(struct yoyo *y)
{
free(y->Kids);
free(y);
}
Does that make sense?
you don't need these lines
y->Kids = malloc(n*sizeof(*Child)); and <br>
free(y->Kids);
because your y contains kids structure in it. And except these , you are going well
y = malloc(sizeof(struct Yoyo));
y->Kids = malloc(n*sizeof(struct Child));

Resources