How to repeat value of array in Flutter - arrays

I'm iOS Developer and new for Flutter. In the Swift language If we want to repeat the same value for a specific time in the Array.
Ex.
If In the Array I want to repeat 0 for 5 times then I can do by one line of code like below.
let fiveZeros = Array(repeating: "0", count: 5)
print(fiveZeros)
// Prints "["0", "0", "0", "0", "0"]"
init(repeating:count:) function used.
So I'm looking for any function or code that works in Flutter.
I do googling but didn't find a solution.

In dart you can use the filled factory of List.
final list = List.filled(5, 0);
print(list); //-> [0, 0, 0, 0, 0]
See more in the list docs.

Starting from Dart 2.3.0 you can use conditional and loop initializers, so for your case it should be:
var fiveZeros = [for (var i = 0; i < 5; ++i) 0];
Everything becomes much flexible and powerful when you want to initialize by expression, not just constant:
var cubes = [for (var i = 0; i < 5; ++i) i * i * i];
is the same as [0, 1, 8, 27, 64].
Conditional elements are also essential taking into account the possibility to build a list of widgets where some of them depend on the state or platform.
More details here

You can use the filled method like what #Edman answered. I just want to add one more way by using generate
final list = new List.filled(5, 0);
print(list);
final list1 = new List.generate(5, (index) {
return 0;
});
print(list1);

Use List.generate method.
var list = List.generate(5, (i) => 'Z');

Related

For loops with promises

I want to write three for loops with promises something like this:
for i = 1 .. 3
for j = 1 .. 5
for k = 1 .. 6
post call to db to check if there is item on location i, j, k
step 1: check 1,1,1
step 2: check 1,1,2 item is found or inc next index
...
I searched for similar questions but I get only one-dimensional array loops examples.
I found this very hard problem and I hope you guys can help me. Thanks.
piping promises can be done linearly. So in your case, you have to first generate an array which holds all possible combinaisons like so:
$locations = [
[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4],
....
];
Then you can easily loop over this array and pipe your promises. Hope this helps
You can't combine a synchronous for loop with asynchronous operations and get things to sequence properly because there's no way to make a for loop "wait" for a promise to finish. The for loop runs synchronously so it will just start all the async operations at once.
So, instead you have to do your iterations another way. If you were iterating just one parameter, there would be a number of ready-made ways to do that, but I'm not aware of any pre-built solutions for iterating three nested variables so you will have to build your own. Here's one way to do it. This method is custom coded for your iterations which makes it a bit less code that a general scheme:
// fn gets called like this fn(i, j, k) and must return a promise
function iterateLevels(fn) {
var i = 1, iMax = 3;
var j = 1, jMax = 5;
var k = 1, kMax = 6;
function next() {
if (k > kMax) {
j++;
k = 1;
}
if (j > jMax) {
i++;
j = 1;
}
if (i > iMax) {
return;
}
return fn(i, j, k).then(function(result) {
k++;
// process result here
// if you want to continue processing, then
return next();
});
}
return next();
}
Here's a working demo implementation using a promise with a random delay: https://jsfiddle.net/jfriend00/q2Lnhszt/
The next() function with the outer scope variables i, j and k is essentially a state machine where each time you call next() it runs the next iteration and updates its state.
This could be made generic so you pass in how many levels of iteration and what the start and stop values for each level are and you could pass in a function for processing the result. Making it generic adds more code to the implementation and makes the logic a little harder to follow.

How to find all sequences of three in an array of values

first question ever here...
I am coding a simple 3-card poker hand evaluator and am having problems finding/extracting multiple "straights" (sequential series of values) from an array of values.
I need to extract and return EVERY straight the array possibly has. Here's an example:
(assume array is first sorted numerically incrementing)
myArray = [1h,2h,3c,3h,4c]
Possible three-value sequences are:
[1h,2h,3c]
[1h,2h,3h]
[2h,3c,4c]
[2h,3h,4c]
Here is my original code to find sequences of 3, where the array contains card objects with .value and .suit. For simplicity in this question I just put "2h" etc here:
private var _pokerHand = [1h,2h,3c,3h,4c];
private function getAllStraights(): Array
{
var foundStraights:Array = new Array();
for (var i: int = 0; i < (_handLength - 2); i++)
{
if ((_pokerHand[i].value - _pokerHand[i + 1].value) == 1 && (_pokerHand[i + 1].value - _pokerHand[i + 2].value) == 1)
{
trace("found a straight!");
foundStraights.push(new Array(_pokerHand[i], _pokerHand[i + 1], _pokerHand[i + 2]));
}
}
return foundStraights;
}
but it of course fails when there are value duplicates (like the 3's above). I cannot discard duplicates because they could be of different suits. I need every possible straight as in the example above. This allows me to run the straights through a "Flush" function to find "straight flush".
What array iteration technique am I missing?
This is an interesting problem. Given the popularity of poker games (and Flash) I'm sure this has been solved many times before, but I couldn't find an example online. Here's how I would approach it:
Look at it like a path finding problem.
Begin with every card in the hand as the start of a possible path (straight).
While there are possible straights:
Remove one from the list.
Find all the next valid steps, (could be none, or up to 4 following cards with the same value), and for each next valid step:
If it reaches the goal (completes a straight) add it to a list of found straights.
Otherwise add the possible straight with the next step back to the stack.
This seems to do what you want (Card object has .value as int):
private function getAllStraights(cards:Vector.<Card>, straightLength:uint = 3):Vector.<Vector.<Card>> {
var foundStraights:Vector.<Vector.<Card>> = new <Vector.<Card>>[];
var possibleStraights:Vector.<Vector.<Card>> = new <Vector.<Card>>[];
for each (var startingCard:Card in cards) {
possibleStraights.push(new <Card>[startingCard]);
}
while (possibleStraights.length) {
var possibleStraight:Vector.<Card> = possibleStraights.shift();
var lastCard:Card = possibleStraight[possibleStraight.length - 1];
var possibleNextCards:Vector.<Card> = new <Card>[];
for (var i:int = cards.indexOf(lastCard) + 1; i < cards.length; i++) {
var nextCard:Card = cards[i];
if (nextCard.value == lastCard.value)
continue;
if (nextCard.value == lastCard.value + 1)
possibleNextCards.push(nextCard);
else
break;
}
for each (var possibleNextCard:Card in possibleNextCards) {
var possibleNextStraight:Vector.<Card> = possibleStraight.slice().concat(new <Card>[possibleNextCard]);
if (possibleNextStraight.length == straightLength)
foundStraights.push(possibleNextStraight);
else
possibleStraights.push(possibleNextStraight);
}
}
return foundStraights;
}
Given [1♥,2♥,3♣,3♥,4♣] you get: [1♥,2♥,3♣], [1♥,2♥,3♥], [2♥,3♣,4♣], [2♥,3♥,4♣]
It gets really interesting when you have a lot of duplicates, like [1♥,1♣,1♦,1♠,2♥,2♣,3♦,3♠,4♣,4♦,4♥]. This gives you:
[1♥,2♥,3♦], [1♥,2♥,3♠], [1♥,2♣,3♦], [1♥,2♣,3♠], [1♣,2♥,3♦], [1♣,2♥,3♠], [1♣,2♣,3♦], [1♣,2♣,3♠], [1♦,2♥,3♦], [1♦,2♥,3♠], [1♦,2♣,3♦], [1♦,2♣,3♠], [1♠,2♥,3♦], [1♠,2♥,3♠], [1♠,2♣,3♦], [1♠,2♣,3♠], [2♥,3♦,4♣], [2♥,3♦,4♦], [2♥,3♦,4♥], [2♥,3♠,4♣], [2♥,3♠,4♦], [2♥,3♠,4♥], [2♣,3♦,4♣], [2♣,3♦,4♦], [2♣,3♦,4♥], [2♣,3♠,4♣], [2♣,3♠,4♦], [2♣,3♠,4♥]
I haven't checked this thoroughly but it looks right at a glance.

Checking arrays in AS3

I'm collecting rows of answers from a database which are made in to arrays. Something like:
for (var i:int = 0; i < event.result.length; i++) {
var data = event.result[i];
var answer:Array = new Array(data["question_id"], data["focus_id"], data["attempts"], data["category"], data["answer"], data["correct"], data["score"]);
trace("answer: " + answer);
restoreAnswer(answer, i);
}
Now, if I trace answer, I typically get something like:
answer: 5,0,2,IK,1.a,3.1,0
answer: 5,0,1,IK,2.a,3.1,0
answer: 4,1,1,AK,3,3,2
From this we see that focus_id 0 (second array item) in question_id 5 (first array item) has been attempted twice (third array item), and I only want to use the last attempt in my restoreAnswer function.
My problem is that first attempt answers override the second attempts since the first are parsed last it seems. How do I go about only calling my restoreAnswer only when appropriate?
The options are:
1 attempts, correct score (2 points)
2 attempts, correct score (1 points)
1 attempt, wrong score (0 points)
2 attemps, wrong score (0 points)
There can be multiple focus_id in each question_id.
Thank you very much! :)
I would consider having the DB query return only the most recent attempt, or if that doesn't work efficiently, return the data in attempt order. You may score question 5 twice, but at least it'll score correctly on the last pass.
You can also filter or sort the data you get back from the server.
Michael Brewer-Davis suggested using the database query to resolve this; normally speaking, this would be the right solution.
If you wait until you get it back from the web method call or whatever in AS3, then consider creating an additional Vector variable:
var vAttempts:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(this.m_iNumQuestions);
You mentioned that it seems that everything is sorted so that earlier attempts come last. First you want to make sure that's true. If so, then before you do any call to restoreAnswer(), you'll want to check vAttempts to make sure that you have not already called restoreAnswer() for that question_id and focus_id:
if (!vAttempts[data["question_id"]])
{
vAttempts[data["question_id"]] = new Vector.<int>(); // ensuring a second dimension
}
if (vAttempts[data["question_id"]].indexOf(data["focus_id"]) == -1)
{
restoreAnswer(answer, i);
vAttempts[data["question_id"]].push(data["focus_id"]);
}
So optimizing this just a little bit, what you'll have is as follows:
private final function resultHandler(event:ResultEvent):void {
var vAttempts:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(this.m_iNumQuestions);
var result:Object = event.result;
var iLength:int = result.length;
for (var i:int = 0; i < iLength; i++) {
var data = result[i];
var iQuestionID:int = data["question_id"];
var iFocusID:int = data["focus_id"];
var answer:Array = [iQuestionID, iFocusID, data["attempts"],
data["category"], data["answer"], data["correct"], data["score"]];
trace("answer: " + answer);
var vFocusIDs:Vector.<int> = vAttempts[iQuestionID];
if (!vFocusIDs) {
vAttempts[iQuestionID] = new <int>[iFocusID];
restoreAnswer(answer, i);
} else if (vFocusIDs.indexOf(iFocusID) == -1) {
restoreAnswer(answer, i);
vFocusIDs.push(iFocusID);
}
}
}
Note: In AS3, Arrays can skip over certain indexes, but Vectors can't. So if your program doesn't already have some sort of foreknowledge as to the number of questions, you'll need to change vAttempts from a Vector to an Array. Also account for whether question IDs are 0-indexed (as this question assumes) or 1-indexed.

Loop through an array of objects and add only the value to another array. Knockout

friends. I have the following issue. I have two observable arrays.
self.NamesArray= ko.observableArray([{"name: John"}, {"name: Mario"}]);
and
self.ValueArray = ko.observable([]);
I would like to loop through the NamesArray and add only the name values to the ValueArray.
So the output ValueArray should contain the following elements in the end:
{John, Mario}
How can this happen? I am very new to JS and I am just researching the Knockout library. Any help with working example will be greatly appreciated. Thanks.
Fiddle: http://jsfiddle.net/PsyComa/RfWVP/
This really depends on your intention behind doing this.
If you want do to this just once, simply iterate over the first array:
// Load current values of the observables
var n = self.NamesArray(), v = self.ValueArray();
// Push all names from n to v
for (var i = 0; i < n.length; i++) {
v.push( n[i].name );
}
// Update the "values" observable
self.ValueArray(v);
The downside with this is that "ValueArray" does not get updated whenever "NamesArray" changes. If you want "ValueArray" to be an array containing all names that can be found in "NamesArray" (and only those!), you can use a computed observable instead:
self.ValueArray = ko.computed(function() {
var n = self.NamesArray(), v = [];
// ...same for loop as above...
return v;
});

multiple instances of the same object spaced out using a loop is only creating one

I had a hard time trying to word my question properly, so i'm sorry if it seems confusing. Also i'm using the flixel library in flash builder. It may not be that important butcause probably anyone that knows a little more than me or even a little AS3 could probably see what i'm doing wrong.
Anyway, what i'm trying to do is basically create 10 instances of this square object I made. all I have to do is pass it an x an y coordinate to place it and it works. so ive tested if i just do:
var testsquare:Bgsq;
testsquare = new Bgsq(0,0);
add(testsquare);
it works fine and adds a square at 0,0 just like i told it to, but i want to add 10 of them then move the next one that's created 25 px to the right (because each square is 25px)
my problem is that I only ever see 1 square, like it's only making 1 instance of it still.
anyone possibly have an idea what I could be doing wrong?
var counter:int = 0;
var bgsqa:Array = new Array;
for (var ibgs:int = 0; ibgs < 10; ibgs++)
{
bgsqa[counter] = new Bgsq(0,0);
bgsqa[counter].x += 25;
add(bgsqa[counter]);
counter++;
}
There's a lot you're doing wrong here.
First off, you're using a pseudo-iterator (counter) to access array elements through a loop instead of, well, using the iterator (ibgs).
Second, I don't see anything in the array (bgsqa) you're iterating through. It's no wonder you're having problems. Here's what you should do.
var bgsqa:Array = [];
for(var i:int=0;i<10;i++)
{
var bgsq:Bgsq = new Bgsq(i * 25, 0);
add(bgsq);
bgsqa.push(bgsq);
}
That should probably do it if your post is accurate.
for (var ibgs:int = 0; ibgs < 10; ibgs++)
{
bgsqa[counter] = new Bgsq(0,0);
bgsqa[counter].x = counter * 25;
add(bgsqa[counter]);
counter++;
}
They start at 0, so applying += is simply adding 25 to 0. This should do the trick.

Resources