I have for example this array:
[
{
"name": "Daniel",
"points": 10,
},
{
"name": "Ana",
"points": 20
},
{
"name": "Daniel",
"points": 40
}
]
And i want delete one "Daniel" and points to the sum of all whit the same name like this:
[
{
"name": "Daniel",
"points": 50,
},
{
"name": "Ana",
"points": 20
}
]
How can i transform it?
I was trying whit two bucles:
for name in persons {
for name2 in persons {
if name == name2 {
//remove the duplicate one and sum his points
}
}
}
but maybe there is a way too much easier than this one
A possible solution is to group the array with Dictionary(grouping:by:) then mapValues to the sum of the points.
The resulting dictionary [<name>:<points>] can be remapped to Person instances
struct Person {
let name: String
let points: Int
}
let people = [
Person(name: "Daniel", points: 10),
Person(name: "Ana", points: 20),
Person(name: "Daniel", points: 40),
]
let result = Dictionary(grouping: people, by: \.name)
.mapValues{ $0.reduce(0, {$0 + $1.points})} // ["Daniel":50, "Ana":20]
.map(Person.init)
print(result) // [Person(name: "Daniel", points: 50), Person(name: "Ana", points: 20)]
Related
sample json data is this:
{
"variations": [
{
"variation_id": 391,
"name": "Fruit Shake - Chocolate, S",
"price": 10,
"attribute": [
{
"attribute_key": "pa_flavor",
"name": "Flavor",
"option": "Chocolate"
},
{
"attribute_key": "pa_size",
"name": "Size",
"option": "S"
}
]
},
{
"variation_id": 385,
"name": "Fruit Shake - Banana, L",
"price": 18,
"attribute": [
{
"attribute_key": "pa_flavor",
"name": "Flavor",
"option": "Banana"
},
{
"attribute_key": "pa_size",
"name": "Size",
"option": "L"
}
]
},
{
"variation_id": 386,
"name": "Fruit Shake - Banana, M",
"price": 15,
"attribute": [
{
"attribute_key": "pa_flavor",
"name": "Flavor",
"option": "Banana"
},
{
"attribute_key": "pa_size",
"name": "Size",
"option": "M"
}
]
}
]
}
my problem is, getting the variation_id where 2 or more attributes matches the array of string.
for example, chosenProduct = ["Banana", "L"]
I tried filter and contains but theres no way to match the other item from chosenProduct.
If I added the next condition, it returns nil
You can try this:
let varID = product.variations?.filter { att in
var matchedAttributes = 0
for thisAttribute in att.attribute {
if chosenProduct.contains(where: {$0 == thisAttribute.option}) {
matchedAttributes += 1
}
}
if matchedAttributes >= 2 {
return true
}
return false
}
Let me know if there's any doubt.
You can try this :
var chosenProduct = ["Banana","L"]
var expectedIds : [Int] = [Int]()
datas.variations?.map{ val in
val.attribute.map({ val2 in
let filtered = val2.enumerated().filter({chosenProduct.contains($0.element.option!)})
if filtered.count == chosenProduct.count{
expectedIds.append(val.variation_id!)
}
})
}
print(expectedIds) // [385]
I put the id's in array because of if you want to change your chosenProcudt example "Banana" (count 1 ). This mapping must be return variation_id like [385,386]
You can a method to Variation to make things easier:
extension Variation {
func attributesMatching(options: [String]) -> [Attribute] {
attribute.filter { options.contains($0.option) }
}
}
Then, you can just write:
let filtered = product.variations.filter { $0.attributesMatching(options: chosenProductOptions).count >= 2 }
print(filtered.map { $0.variationID })
I'm trying to send a JSON payload in my POST request but I'm not sure on how to format it correctly to use arrays. This below is what the correct JSON itself looks like:
{
"animal": "dog",
"contents": [{
"name": "daisy",
"VAL": "234.92133",
"age": 3
}]
}
I have this so far:
group := map[string]interface{}{
"animal": "dog",
"contents": map[string]interface{}{
"name": "daisy",
"VAL": "234.92133",
"age": 3,
},
}
But I can't figure out how to do array of contents (the square brackets), only the curly brackets from "contents".
The quick answer:
group := map[string]interface{}{
"animal": "dog",
"contents": []map[string]interface{}{
{
"name": "daisy",
"VAL": "234.92133",
"age": 3,
},
},
}
But as already said in the comments it is better (type safety) to use structs instead:
type Animal struct {
Type string `json:"animal"`
Contents []AnimalContent `json:"contents"`
}
type AnimalContent struct {
Name string `json:"name"`
Value string `json:"VAL"`
Age int `json:"age"`
}
Then create with:
group := Animal{
Type: "dog",
Contents: []AnimalContent{
{
Name: "daisy",
Value: "234.92133",
Age: 3,
},
},
}
// to transform to json format
bts, err := json.Marshal(group)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(bts))
I have a json as below
{
"Animals": [
{
"Name": "monkey",
"Age": 4
},
{
"Name": "lion",
"Age": 3
},
{
"Name": "lion",
"Age": 3,
"Misc": "001"
}
]
}
2 elements out of 3 inside json array has the Name and Age. The only difference is that 3rd element has Misc and the 2nd does not have Misc.
How to get the record having Misc when there are 2 records with same Name and Age?
Below is what I tried
parsedJson?.Animals = parsedJson?.Animals?.unique().findAll{animal -> animal?.Misc?.trim() ? animal?.Misc?.trim() : site?.Name?.trim() };
Looks like I missed one more statement or I missed something inside unique()
I also tried
parsedJson?.Animals = parsedJson?.Animals?.unique{a1,a2 -> a1?.Misc <=> a2?.Misc}
but still not get what I want
What I want is
{
"Animals": [
{
"Name": "monkey",
"Age": 4
},
{
"Name": "lion",
"Age": 3,
"Misc": "001"
}
]
}
One way to go about this is by grouping the elements and then just merge
the maps.
groupBy is used to group the elements by their "primary key" -- lets
assume, that this is Name and Age. The resulting data structure is
a map with [it.Name, it.Age] tuples and keys and a list of elements,
that hold that property.
Next reduce over the list of maps and just merge them. This assumes,
that the information there does not contradict itself (e.g. only adds to
the result). Otherwise the last map would just win.
def data = [["Name": "monkey", "Age": 4],
["Name": "lion", "Age": 3],
["Name": "lion", "Age": 3, "Misc": "001"]]
println data.groupBy{[it.Name, it.Age]}.collect{ _, xs -> xs.inject{ acc, x -> acc.putAll x; acc } }
// → [[Name:monkey, Age:4], [Name:lion, Age:3, Misc:001]]
I have fetched data from a JSON file.. But when I tried to fetch another data from it, am unable to do so as it is a nested array... I know the solution can arrive easily but this is the first time am trying to loop a JSON file.. so kindly give your inputs.
SampleData = {
"squadName": "Super hero squad",
"homeTown": "Metro City",
"formed": 2016,
"secretBase": "Super tower",
"active": true,
"members": [
{
"name": "Molecule Man",
"age": 29,
"secretIdentity": "Dan Jukes",
"powers": [
"Immortality",
"Turning tiny",
"Radiation blast"
]
},
{
"name": "Madame Uppercut",
"age": 39,
"secretIdentity": "Jane Wilson",
"powers": [
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes"
]
},
{
"name": "Eternal Flame",
"age": 1000,
"secretIdentity": "Unknown",
"powers": [
"Immortality",
"Heat Immunity",
"Inferno",
"Teleportation",
"Interdimensional travel"
]
}
]
};
GetJsonData() {
console.log(this.SampleData["powers"]);
for (let i = 0; i < this.SampleData["powers"].length; i++) {
if (this.SampleData["powers"][i].Immortality) {
console.log(this.SampleData.powers[i]);
}
}
}
{name: "Molecule Man", age: 29, secretIdentity: "Dan Jukes", powers: Array(3)}
{name: "Eternal Flame", age: 1000, secretIdentity: "Unknown", powers: Array(3)}
Your code needs to follow the structure of the JSON data; in particular, these are all valid things you could print:
console.log(this.SampleData.squadName);
console.log(this.SampleData.homeTown);
console.log(this.SampleData.members[0].name);
console.log(this.SampleData.members[0].powers[0]);
If you wanted to loop through each member and print their info, that might look like this:
this.SampleData.members.forEach(member => {
let powerString = member.powers.join(', ');
console.log('Name: ' + member.name);
console.log('Age: ' + member.age);
console.log('Powers: ' + powerString);
});
I used a forEach, but you can also use a for (let i = loop.
I know how to operate on array of objects but never had the necessity to push one array data into another. I need to push an array of objects into another array with only 2 fields of the object. Right now my object format is somewhat like this
data: [{
"name": "Btech",
"courseid": "1",
"courserating": 5,
"points": "100",
"type": "computers"
},
{
"name": "BCom",
"courseid": "2",
"courserating": 5,
"points": "100",
"type": "computers"
}];
I want to push this into another array but I want only courseid and name in the object. I've read that we need to initialise the object in the constructor, use slice() and a few other functions and then push but I don't know how can I do it for mine since I need to push one array data into another.Kindly someone help me in this regard.
You're looking for the array map() method:
const newArray = array.map(o => {
return { name: o.name, courseid: o.courseid };
});
Try this:
let data = [{
"name": "Btech",
"courseid": "1",
"courserating": 5,
"points": "100",
"type": "computers"
},
{
"name": "BCom",
"courseid": "2",
"courserating": 5,
"points": "100",
"type": "computers"
}];
let other = []; // your other array...
data.map(item => {
return {
courseid: item.courseid,
name: item.name
}
}).forEach(item => other.push(item));
console.log(JSON.stringify(other))
// => [{"courseid":"1","name":"Btech"},{"courseid":"2","name":"BCom"}]
You can simply do it like this.
//assign your array of object to variable
var youArray:Array<any>= [{
"name": "Btech",
"courseid": "1",
"courserating": 5,
"points": "100",
"type": "computers"
},
{
"name": "BCom",
"courseid": "2",
"courserating": 5,
"points": "100",
"type": "computers"
}];
var resultArray:Array<any>=[] //empty array which we are going to push our selected items, always define types
youArray.forEach(i=>{
resultArray.push(
{
"name":i.name,
"courseid":i.courseid
});
});
console.log(resultArray)
if you still have doubts about this.please follow this url
Map to a returning JSON data, subscribe it to an existing array or an empty one. #typescript
let pictimeline= [];
var timeline = this.picService.fetchtimeline(this.limit)
.map((data : Response) => data.json())
.subscribe(pictimeline=> this.pictimeline = pictimeline);
console.log(this.pictimeline);