Put all maps inside one list - arrays

My problem with Flutter is when I'm converting an array to a list, there is every item is a separated list and I want all the items in just one list.
Example output when putting 2 items:
[{title: ITEM1}, {title: ITEM2}]
I want to put like this:
[{title: ITEM1, title: ITEM2}]
I hope you guys understand the problem
void _addPecas() {
if ((_pecasController.text.isEmpty) ||
((_pecasController.text.trimLeft() == ("")))) {
print("Campo Vazio");
} else {
setState(() {
Map<String, dynamic> newPeca = Map();
newPeca["title"] = _pecasController.text.trimLeft();
_pecasController.text = "";
_pecasList.add(newPeca);
print(_pecasList);
});
}
}

if [{title: ITEM1, title: ITEM2}] is what you want to achieve,
The problem here is that you are creating a new Map called newPeca every time your function runs. .
Map<String, dynamic> newPeca = Map();
So by the time you set your values you call _pecasList.add(newPeca); that new map will be appended to your List thus you get [{title: ITEM1}, {title: ITEM2}]
Working with the assumption that you want only one Map in _pecaList, _newPeca should always reference that one Map
Map<String, dynamic> newPeca = _pecaList[0]
then you can add your desired values newPeca["title"] = _pecasController.text.trimLeft();
One more problem you'll run into, you want to have duplicate keys in the Map, which is not possible.
The newer value in the map will overwrite the existing one.
E.g
newPeca[title] = "Item 1"
newPeca[title] = "Item 2"
newPeca[title] will end up being Item 2

As I understood, you are asking for one Map inside List and add values into that Map and finally add it into a List. Here is how you can do it:
Map<String, dynamic> newPeca = Map();
if (_pecasController.text.isEmpty ||
_pecasController.text.trimLeft() == ("")) { // you had too much unwanted brackets here
print("Campo Vazio");
} else {
setState(() {
newPeca["title"] = _pecasController.text.trimLeft(); // you have to have unique key if you want to keep in one Map. See the dart pad example I have provided a link below
_pecasController.text = "";
// _pecasList = [newPeca]; // this is also working without outside .add() but if the list is long, im not recommending this.
print(_pecasList);
});
}
// outside the iteration
_pecasList.add(newPeca);
Edit simple dart example in dartpad
Update:
Make sure this: Map<String, dynamic> newPeca = Map(); outside the iteration. This way you are not creating Map for each and every iteration. You are adding to same map and that map you should add after each iteration to the List or just create empty list assign as a new list in each and every iteration(Btw, not the performant way).
Secondly, when you add to the list inside iteration each and every time map will add to the list.
Finally, Even if you make those right, your map will not take same value as title because the reason is your key of the map entry is title and you cannot have duplicate keys inside map and the list should be outside the iteration.

Related

create a new Array with filtered out props

I have been trying to filter an Array by its props and not by its value so my original array would be -
const orignalArray =[
{id: 1, name:"jim", email:"jim#mail.com",age:20},
{id: 1, name:"jom", email:"jom#mail.com",age:30}
]
id like to be able to use (n) amount of filters.
My output array would look ideally look like this
const filterList["id","age"]
const newArray=[{name:"jim", email:"jim#mail.com"},{ name:"jom", email:"jom#mail.com"}]
I have tried to use filter() but cant seem to get it to work.
any help is much appreciated.
In this case you aren't filtering the array rather creating a new one based on the original with derived elements from each. To achieve this you can use the array map function to loop over the array and create a new one with new objects without the desired properties, e.g.:
function removeArrayElementProps(arr, propsToRemove) {
return arr.map((element) => {
// Create a copy of the original element to avoid modifying the original
const newElement = {...element};
// Remove the desired properties from the new element
propsToRemove.forEach((propToRemove) => {
delete newElement[propToRemove];
});
// Returning the modified element in map puts it in thew new arry
return newElement;
});
}
Then you simply call:
const newArr = removeArrayElementProps(orignalArray, ['id','age']);
This loops over the array, creates a copy of each element, and removes the specified properties from the element.

how do I get rid of this simple SwiftUI error?

I just wanna get all the records from the transaction variable and save it to an array.i tried and all I am getting is this constant error. please help me, I just wanna all models(records) to be saved on an array.
Type '()' cannot conform to 'View'
#State private var transactions: [Transactions] = [Transactions]()
ForEach(transactions, id: \.self) { transaction in
timexxx[0] = transaction.timexx ?? "0"
Text(timexxx[0] ?? "0")
}
enter image description here
Like what #multiverse has suggested
ForEach loop expects some sort of View but you are giving it or attempting to give an "array" (it only wants View)
Here is an updated code where you give the ForEach what it wants and you append to your timexxx array
ForEach(Array(transactions.enumerated()), id: \.offset) { (offset, transaction) in
Text(transaction.timexx ?? "\(offset)")
.onAppear {
timexxx[offset] = transaction.timexx ?? "\(offset)"
}
}
Update
for your question
"how do I do this with a simple "For" loop ? let's say I wanna do this operation in a simple class."
This is how it's done.
I removed the view Text.
for (i, transaction) in transactions.enumerated() {
timexxx[i] = transaction.timexx ?? "0"
}
Ok , so this is an error i faced as well, when i was learning SwiftUI( i am still a beginner), so now we need to understand , what does this error actually means, in this case the ForEach loop expects some sort of View but you are giving it or attempting to give an "array" (it only wants View)....
If you want values to be transferred to an array just simply create a function and do it .....
say you have a class and inside of which you do
#Published var song = [Song]()
then what you do is inside a function like loadData()
objects is the array whose elements you want transferred and most likely those elements belong to a Struct like Song here(if not its even simpler just use what ever type it has like Int, String etc.), this way all your elements will get transferred to song from objects
func loadData() {
song = objects.map {
artist in
Song(album: artist.album, artistImage: artist.artistImage)
}
}
Here i add the simplest possible way to transfer from one array to other
var objects = [1,2,3,4,5]
var song = [Int]()
func loadData() {
song = objects.map { $0 }
}
loadData()
print(song)
//[1,2,3,4,5]

Remove random item from array and push to new array

Thank you in advance! I'm new to coding and learning how to deal with Arrays. I am trying to remove random items from an array (deck of cards), and populate a new array (called hand). The problem I always seem to have with arrays is taking the results of one and creating a new function/array/ etc.. Currently, I am outputting 2 separate arrays and I can't seem to push them into one.
let deck = ["dA","dQ","dK","dJ","d10","d09","d08",
"d07","d06","d05","d04","d03","d02","hA","hQ","hK",
"hJ","h10","h09","h08","h07","h06","h05","h04","h03"];
var hand = deck.splice(Math.floor(Math.random()*deck.length),1);
console.log(hand)
var hand = deck.splice(Math.floor(Math.random()*deck.length),1);
console.log(hand);
In your code, just you need to push the value returned from splice method rather than directly assigning it.
By this way every time a new value that gets deleted and will be added to the new array called hand. Hope this helps. :-)
let deck = ["dA","dQ","dK","dJ","d10","d09","d08",
"d07","d06","d05","d04","d03","d02","hA","hQ","hK",
"hJ","h10","h09","h08","h07","h06","h05","h04","h03"];
var hand = [];
const getSelectedCard = () => deck.splice(Math.floor(Math.random()*deck.length),1)
let selectedCard = getSelectedCard();
hand.push(...selectedCard) //or hand.push(selectedCard[0])
console.log(hand);
selectedCard = getSelectedCard();
hand.push(...selectedCard)
console.log(hand);

Find the element in custom array and append the value in one of its property(which is also an array) of custom array in swift

#objc class CplModel:NSObject {
var cplModel:UserCplModel = UserCplModel(json: [:])
var courseData:[CourseModel] = [CourseModel]()
var feedData:[FeedsModel] = [FeedsModel]()
var assessmentData:[AssessmentModel] = [AssessmentModel]()
var userCourseData:[UserCourseModel] = [UserCourseModel]()
init(jsonUserCPlModel:[String:Any]){
if let value = jsonUserCPlModel[""] as? [String:Any]{
self.cplModel = UserCplModel(json: value)
}
}
init(jsonAssessmentAndCourseData:[String]) {
}
}
I am making three Firebase calls and all three are interlinked and want to populate data in above model.
Here comes the issue:
For 1st API call I need to populate only cplModel:UserCplModel property
For 2nd ApI call I need to populate courseData:[CourseModel] and assessmentData:[AssessmentModel]
But the index should remain the same for every populating data.
I mean to say is for 1st index of cplModel, I need to insert the courseData or assessmentData but the response of 2nd API comes later and I need to insert the data in particular index only.

Appending Class Objects to Array [Swift]

I have a RestAPI that pulls JSON data from a webpage, and because I want to follow MVC programming standards, I want to fetch this data through a "Data List" class that instantiates the RestAPI Class.
I have a class called "Card", which provides the basic structure of a type of data object. I have a class called "CardList" whose initialization creates an Array of the "Card" Classes.
However, I'm having trouble appending Card Class data to my CardList Array.
Here is the code for CardList Class:
class CardList {
var cards: [Card]
static var sharedInstance = CardList()
//MARK - Initalize
private init(){
//Dummy Data
let helm = Card(name: "Helm of Testing", cost: 10, type: "Equipment", subType: "Head Armor", description: "Some say the Helmet of Testing helps keep it's wearers mind clear.")
//Add to Array
var c = [helm]
let items: NSMutableArray = []
//Get API Array
RestApiManager.sharedInstance.getElements { (json: JSON) in
let results = json["results"]
for (_, subJson) in results {
let card:AnyObject = subJson["card"].object
items.addObject(card)
}
for var i = 0; i < items.count; ++i{
let data:JSON = JSON(items[i])
let newCard = Card(name: data["title"].stringValue, cost: Int(data["cost"].string!)!, type: data["type_id"].stringValue, subType: data["subtype_id"].stringValue, description: data["description"].stringValue)
c.append(newCard)
}
}
cards = c.sort { $0.cost < $1.cost }
}
//END Class
}
So basically on initialization, this class creates a dummy Card, adds it to an array called "c". An array called "items" is created. There RestApiManager returns JSON data, for every type of data returned in the results, it gets added into the "items" array.
We then loop through the "items" array, reading it as JSON (I'm using the SwiftyJSON plugin/code snip) and creating a new "Card" Class for each item in the array. We then append the "Card" to the "c" Array.
Finally we take the Card Array "cards" and set it equal to the "c" Array sorted by it's value cost.
The Problem:
After running the code, the "cards" Array only returns the dummy card named "helm", and none of the data added to the "c" array.
Notes:
Yes, my Api is working, if I print the values in the "for var i = 0" loop, it is printing correct values. If I print the "c.count" in the same loop, I get two (The API is only returning 1 other data set, or "Card"). If I print the "c.count" outside of that loop, after the loop, it says there is only 1 item in the Array when there should be two (the dummy data and the data returned from the JSON call).
So, it's clearly something with my syntax. Or maybe I'm making things more complicated than they need to. I'm fairly new to Swift and slightly confused. I just need someone else to look at my code.
Thank you in advance.
RestApiManager.sharedInstance.getElements works asynchronously.
The block containing the data is executed after the init function exits.
Move the code to assign and sort the array into the block.
...
for var i = 0; i < items.count; ++i{
let data:JSON = JSON(items[i])
let newCard = Card(name: data["title"].stringValue, cost: Int(data["cost"].string!)!, type: data["type_id"].stringValue, subType: data["subtype_id"].stringValue, description: data["description"].stringValue)
c.append(newCard)
}
cards = c.sort { $0.cost < $1.cost }
}
}

Resources