Convert Array of Objects into Array of Array of strings - arrays

In my angular app, I get the values from service as an array of objects like below.
temp= [
{
"a": "AAA",
"b": "bbbb",
"c": "CCCC",
"d": "ddddd",
},
{
"a": "lmn",
"b": "opq",
"c": "rst",
"d": "uvw",
}
]
I need to format this temp to array of array of strings:
newTemp =
[
['AAA', 'bbbb', 'CCCC', 'ddddd'],
['lmn', 'opq', 'rst', 'uvw'],
];
Should we need to do a forloop on each object or is there any straight forward way.

You can use Array.map
let newArray = arr.map(a => Object.values(a))
If you cant use Object.values
let newArray = arr.map(a => Object.keys(a).map(k => a[k]))
Output
(2) [Array(4), Array(4)]
0:(4) ["AAA", "bbbb", "CCCC", "ddddd"]
1:(4) ["lmn", "opq", "rst", "uvw"]

Try the following :
temp= [
{
"a": "AAA",
"b": "bbbb",
"c": "CCCC",
"d": "ddddd",
},
{
"a": "lmn",
"b": "opq",
"c": "rst",
"d": "uvw",
}
]
var newTemp = [];
temp.forEach(function(obj){
var arr = [];
Object.keys(obj).forEach(function(key){
arr.push(obj[key]);
})
newTemp.push(arr);
});
console.log(newTemp);

Related

Calculation on dynamic data in React

This array can be fetched by .map in return()
[
{
"a": "3",
"Count": "3",
"b": "299.98999786376953",
"c": "30",
"d": "30"
},
{
"a": "9",
"Count": "1",
"b": "99.98999786376953",
"c": "10",
"d": "9"
}
]
I want to apply formulas on it like:
a = a/Count;
b = (b/(Count*10))*100;
c = (c/(Count*10))*100;
d = (d/(Count*10))*100;
Also find e = (a+b+c+d)/4;
then display them in each table row's data using .map
I tried npmjs.com/package/react-equation, it can do calculations directly in return() however don't fetch dynamic variables of array inside return(). I also tried creating a function outside return add(a,b){return a+b) and calling it inside return(), neither do it work and tried some other methods as well.
Here is a sample code that can help you continue your work. It uses map to transform your string array to float array and also return the new calculated objects
const array = [
{
"a": "3",
"Count": "3",
"b": "299.98999786376953",
"c": "30",
"d": "30"
},
{
"a": "9",
"Count": "1",
"b": "99.98999786376953",
"c": "10",
"d": "9"
}
]
const newArray = array.map(obj => {
const a = parseFloat(obj.a) / parseFloat(obj.Count);
const b = (parseFloat(obj.b)/(parseFloat(obj.Count) * 10)) * 100
const c = (parseFloat(obj.c)/(parseFloat(obj.Count) * 10)) * 100
const d = (parseFloat(obj.d)/(parseFloat(obj.Count) * 10)) * 100
return { a, b, c, d, e: (a+b+c+d)/4}
})
console.log(array, newArray)
I don't think you can really use map because you're doing different calculations for a and for b,c,d and for e, and also because the calcultions on a depends on value of Count. You could just define a function that accepts the entire object and performs the calculations like so:
const performCalculations = (obj) => {
obj.a = obj.a / obj.Count;
obj.b = (obj.b/(obj.Count*10))*100;
obj.c = (obj.c/(obj.Count*10))*100;
obj.d = (obj.d/(obj.Count*10))*100;
obj.e = (obj.a + obj.b + obj.c + obj.d)/4;
return obj;
}
Edit: you can use map see #Apostolos answer

Unwind 3 arrays in MongoDB

MongoDB collection data with multiple arrays:
{
"_id": ObjectId("61aa6bf1742b00f59b894eb7"),
"first": ["abc", "def", "ghi"],
"last": ["rst", "uvw", "xyz"],
"numb": ["12", "34", "56"]
}
Expected output where the data in the arrays should be in this format:
{
"first": "abc",
"last": "rst",
"numb": "12"
},
{
"first": "def",
"last": "uvw",
"numb": "34"
},
{
"first": "ghi",
"last": "xyz",
"numb": "56"
}
You can make use of $zip to "transpose" multiple arrays (as many as you'd like actually):
// {
// first: ["abc", "def", "ghi"],
// last: ["rst", "uvw", "xyz"],
// numb: ["12", "34", "56"]
// }
db.collection.aggregate([
{ $project: { x: { $zip: { inputs: ["$first", "$last", "$numb"] } } } },
// { x: [["abc", "rst", "12"], ["def", "uvw", "34"], ["ghi", "xyz", "56" ]] }
{ $unwind: "$x" },
// { x: [ "abc", "rst", "12" ] }
// { x: [ "def", "uvw", "34" ] }
// { x: [ "ghi", "xyz", "56" ] }
{ $replaceWith: {
$arrayToObject: { $zip: { inputs: [["first", "last", "numb"], "$x"] } }
}}
])
// { first: "abc", last: "rst", numb: "12" }
// { first: "def", last: "uvw", numb: "34" }
// { first: "ghi", last: "xyz", numb: "56" }
This:
zips the 3 arrays such that elements at the same index will get grouped into the same sub-array.
$unwinds (explodes/flattens) those sub-arrays.
transforms the resulting arrays into objects to fit your expected output format:
by $zipping (again!) the keys we want to associate with the array's values (the keys: ["first", "last", "numb"] and the values: "$x")
and $replaceWith the current document with the result of the $zip.
Note that prior to Mongo 4.2, you can use $replaceRoot instead of $replaceWith.
Query
map on indexes to combine the same index members to 1 document
keeps the _id also to know from which document those came from
and the index to sort after
for each index take the element from each array
unwind
sort by _id and index to get the results sorted like it was in the arrays
*indexes are computed using the biggest array, to be safe, in case you already know that all are the same size, you can replace the :
{"$max": [{"$size": "$first"}, {"$size": "$last"}, {"$size": "$numb"}]}
with the size of any array for example(we need the biggest to work):
{"$size": "$first"}
Test code here
aggregate(
[{"$project":
{"data":
{"$map":
{"input":
{"$range":
[0,
{"$max":
[{"$size": "$first"}, {"$size": "$last"}, {"$size": "$numb"}]}]},
"in":
{"_id": "$_id",
"index": "$$this",
"first": {"$arrayElemAt": ["$first", "$$this"]},
"last": {"$arrayElemAt": ["$last", "$$this"]},
"numb": {"$arrayElemAt": ["$numb", "$$this"]}}}}}},
{"$unwind": {"path": "$data"}},
{"$replaceRoot": {"newRoot": "$data"}},
{"$sort": {"_id": 1, "index": 1}},
{"$unset": ["index"]}])

Create Array of Dictionaries iOS Swift

I am trying to implement an array of dictionaries but I get an output different from my expectation.
In the following code snippet I create an array, a dictionary and execute the append operation:
var MemberArray = [[String: Any]]()
let dict = ["member_status":"1",
"member_id": memid ,
"membership_number": memshpid,
"name": memname,
"mobile":memno ,
"billing":"1"] as NSDictionary
MemberArray.append(dict as! [String : Any])
I need it to be this:
[
{
"member_status": 1,
"member_id": 3,
"membership_number": "GI99010286",
"name": "Thomas",
"mobile": "9873684678",
"billing": 0
},
{
"member_status": 1,
"member_id": 5,
"membership_number": "GI99010144",
"name": "Raj",
"mobile": "9873684678",
"billing": 1
}
]
But I get the following:
[
[
"member_status": 1,
"member_id": 3,
"membership_number": "GI99010286",
"name": "Thomas",
"mobile": "9873684678",
"billing": 0
],
[
"member_status": 1,
"member_id": 5,
"membership_number": "GI99010144",
"name": "Raj",
"mobile": "9873684678",
"billing": 1
]]
How can I achieve my goal?
For that you have to serialize that array. Here data is that array :
let dataSet = try! JSONSerialization.data(withJSONObject: data, options: JSONSerialization.WritingOptions.prettyPrinted)
let jsonString = NSString(data: dataSet, encoding: String.Encoding.utf8.rawValue)!

Ruby merge arrays without duplicates then use higher value out of duplicate array

i'm working on a version control system in which chef cookbook version numbers are specified in multiple different environments.
I've been able to merge the two environment files together using this format --
source = JSON.parse(File.read("A.json"))
destination = JSON.parse(File.read("B.json"))
source = destination.merge(source)
The values of each file are in this format --
'A'
{
"a": "v2.0.18",
"b": "v5.0.2",
"c": "v17.0.0",
"d": "v9.0.0",
}
'B'
{
"a": "v1.0.18",
"b": "v4.0.0",
"c": "v20.0.0",
"d": "v7.0.0"
}
Currently does --
{
"a": "v2.0.18",
"b": "v5.0.2",
"c": "v17.0.0",
"d": "v9.0.0",
}
What i'd like it to do --
{
"a": "v2.0.18",
"b": "v5.0.2",
"c": "v20.0.0", #keeps higher value
"d": "v9.0.0",
}
Any help would be greatly appreciated.
Thanks
You can use Hash#merge, but you also need to define how the comparison is made between two strings.
major_minor converts "v2.0.18" to [2,0,18], which can be compared to other version arrays to find the maximum.
source = {
"a": "v2.0.18",
"b": "v5.0.2",
"c": "v17.0.0",
"d": "v9.0.0",
}
destination = {
"a": "v1.0.18",
"b": "v4.0.0",
"c": "v20.0.0",
"d": "v7.0.0"
}
def major_minor(version)
version.scan(/\d+/).map(&:to_i)
end
p source.merge(destination){|key, old, new| [old, new].max_by{|v| major_minor(v) } }
#=> {:a=>"v2.0.18", :b=>"v5.0.2", :c=>"v20.0.0", :d=>"v9.0.0"}
Hash#merge is what you're looking for:
a.merge(b) do |key, old_val, new_val|
Gem::Version.new(old_val[1..-1]) > Gem::Version.new(new_val[1..-1]) ? old_val : new_val
end
#=> {:a=>"v2.0.18", :b=>"v5.0.2", :c=>"v20.0.0", :d=>"v9.0.0"}
As #Stefan suggested, the above could be improved by incorporating the approach #Eric Duminil used in his answer:
a.merge(b) { |key, *values| values.max_by { |v| Gem::Version.new(v[1..-1]) } }
You can use merge passing a block to choose which value should be chosen when the key is duplicated.
merge takes additional argument block to figure out which key to keep in case both hashes has same key
a = {
"a": "v2.0.18",
"b": "v5.0.2",
"c": "v17.0.0",
"d": "v9.0.0",
}
b = {
"a": "v1.0.18",
"b": "v4.0.0",
"c": "v20.0.0",
"d": "v7.0.0"
}
c = a.merge(b) {|k, v1, v2| [v1, v2].max}
=> {:a=>"v2.0.18", :b=>"v5.0.2", :c=>"v20.0.0", :d=>"v9.0.0"}

How to create an array of dictionaries?

new to programming!
I'm trying to create an array of dictionaries inside a struct in Swift like so:
var dictionaryA = [
"a": "1",
"b": "2",
"c": "3",
]
var dictionaryB = [
"a": "4",
"b": "5",
"c": "6",
]
var myArray = [[ : ]]
myArray.append(dictionaryA)
myArray.append(dictionaryB)
This works fine in a playground, but when I put it into an Xcode project, inside a struct, the lines with the append function produce the error "Expected declaration".
I've also tried using the += operator with the same result.
How can I successfully construct this array inside the struct?
From your error Expected declaration, I assume you are doing like:
struct Foo {
var dictionaryA = [
"a": "1",
"b": "2",
"c": "3",
]
var dictionaryB = [
"a": "4",
"b": "5",
"c": "6",
]
var myArray = [[ : ]]
myArray.append(dictionaryA) // < [!] Expected declaration
myArray.append(dictionaryB)
}
This is because you can place only "declarations" in the struct body, and myArray.append(dictionaryA) is not a declaration.
You should do that somewhere else, for example in the initializer. The following code compiles.
struct Foo {
var dictionaryA = [
"a": "1",
"b": "2",
"c": "3",
]
var dictionaryB = [
"a": "4",
"b": "5",
"c": "6",
]
var myArray = [[ : ]]
init() {
myArray.append(dictionaryA)
myArray.append(dictionaryB)
}
}
But as #AirspeedVelocity mentioned, you should provides more information about myArray, or myArray would be Array<NSDictionary> which I think you don't expect.
Anyway, the correct solution would vary depending on what you really trying to do:
Maybe or maybe not, what you want is something like:
struct Foo {
static var dictionaryA = [
"a": "1",
"b": "2",
"c": "3",
]
static var dictionaryB = [
"a": "4",
"b": "5",
"c": "6",
]
var myArray = [dictionaryA, dictionaryB]
}
But, I don't know, why don't you just:
struct Foo {
var myArray = [
[
"a": "1",
"b": "2",
"c": "3",
],
[
"a": "4",
"b": "5",
"c": "6",
]
]
}
The problem lies with this line:
var myArray = [[ : ]]
You need to tell Swift what type myArray is – [[:]] isn’t enough information.
You can either do it the explicit way:
var myArray: [[String:String]] = [[ : ]]
Or, if practical, implicitly using the first or both values you plan to put in:
var myArray = [dictionaryA]
var myArray = [dictionaryA,dictionaryB]
(as an alternative to the explicit empty version, you can also write var myArray = [[String:String]](), which is shorthand for var myArray = Array<Dictionary<String,String>>())
var arrayOfDict = [[String: Int]]()
// Create a dictionary and add it to the array.
var dict1: [String: Int] = ["age": 20]
arrayOfDict.append(dict1)
// Create another dictionary.
var dict2: [String: Int] = ["rank": 5].
arrayOfDict.append(dict2)
// Get value from dictionary in array element 0.
if let value = arrayOfDict[0]["age"] {
print(value)
}
Output
20
Or you can use an array of tuples that´s even easier, like this:
var myArray:[(a:String,b:String,c:String)] = []
And append any element you need later:
self.myArray.append((a:"A",b:"B",c:"c"))
And to use them just:
self.myArray[index].a
self.myArray[index].b
self.myArray[index].c

Resources