Hi i need merge two object with mergewith in lodash ...
object1 = {
"a": {
"name": "masoud", "age": 3, "user": "masmas"
},
"b" : {
"name": "milad", "age": 13, "user": "milmil"
}
}
object2 = {
"b" : {
"pythonSkill" : 18 , "HTMLSkill" : 15
} ,
"c" : {
"phpSkill" : 15 , "CSSSkill" : 16
},
"a" : {
"javaSkill" : 20 , "reactSkil" : 10
} ,
}
and finally combined object sample :
final = {
"a": {
"name": "masoud", "age": 3, "user": "masmas", "persianLanguage": 20, "englishLanguage": 10
},
"b" : {
"name": "milad", "age": 13, "user": "milmil" , "pythonSkill": 18, "HTMLSkill": 15
}
}
Each object does not have a specific number of internal objects and may be different each time .
one time Object1 have a , b , c , .... , m & other time Object1 have m , n , o , c , ...
Object2 similar object1 ...
Different scenarios
1- if Object1 have "a" and object2 have "a" , finally object must have "a" ..
2- if Object1 have not "a" and object2 have "a" , finally object have not "a" ..
3- if Object1 have "a" and object2 have not "a" , finally object have not "a"
I don't know about using _.mergeWith, this seems to me to be rather difficult but you can use _.mapValues and _.pickBy to achieve the desired result relatively easily
object1 = {
"a": {
"name": "masoud", "age": 3, "user": "masmas"
},
"b" : {
"name": "milad", "age": 13, "user": "milmil"
},
"d" : {
"name": "nassim", "age": 32, "user": "nm1"
}
}
object2 = {
"b" : {
"pythonSkill" : 18 , "HTMLSkill" : 15
} ,
"c" : {
"phpSkill" : 15 , "CSSSkill" : 16
},
"a" : {
"javaSkill" : 20 , "reactSkil" : 10
} ,
}
let final = _.mapValues(_.pickBy(object1, (v,k) => object2[k]), (v, k, o) => {
return { ...v, ...object2[k] }
});
console.log(final)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>
Related
I would like to get combined list from sublists of an object list.
I have a list object like:
users: [
{
name: "a"
cars: [
"z1",
"z2"
]
},
{
name: "b"
cars: [
"x1",
"x2"
]
}
]
and result should be:
cars = ["z1", "z2", "x1", "x2"]
The main reason is that I need to execute resource on each element:
resource "some_resource" "some_resource_name" {
for_each = var.cars
car_name = each.value
}
If there is a way to do it directly in resource, perfect. Or if I need to pre-build the list in locals that also is not a problem.
How do I do that?
This can be achieved easily with combining a splat expression with flatten function:
locals {
cars = flatten([
var.users[*].cars
])
}
Other solution would be to use a for expression:
locals {
cars = flatten([
for user in var.users: user.cars
])
}
The result for cars in both cases will be:
cars = [
"z1",
"z2",
"x1",
"x2",
]
local {
cars = flatten([
for user, cars in var.users : [
for car in cars: {
user = user
car = car
}
]
])
}
will not produce the perfect result but is a working solution
result will be:
[
{
user = "a",
car = "z1"
},
{
user = "a",
car = "z2"
},
{
user = "b",
car = "x1"
},
{
user = "b",
car = "x2"
}
]
{
"data": [
{
"id": 10,
"title": "Administration",
"active": true,
"type": {
"id": 2,
"name": "Manager"
}
},
{
"id": 207,
"title": "MCO - Exact Match 1",
"active": true,
"type": {
"id": 128,
"name": "Group"
}
},
{
"id": 1201,
"title": "Regression",
"active": false,
"type": {
"id": 2,
"name": "Manager"
}
}
]
}
i am trying to create a tuple in the below format using linq. not sure how to start with group/aggregate. Any help is appreciated. I went over few threads and could not able to find something similar to this.
var tuple = new List<Tuple<int, List<Dictionary<int,bool>>>();
2 10, true
1201, false
128 207, true
Here is a full working code:
var o = new {
data = new [] {
new {
id = 10,
title = "Administration",
active = true,
type = new {
id = 2,
name = "Manager"
}
},
new {
id = 207,
title = "MCO - Exact Match 1",
active = true,
type = new {
id = 128,
name = "Group"
}
},
new {
id = 1201,
title = "Regression",
active = false,
type = new {
id = 2,
name = "Manager"
}
}
}
};
var result = o.data.GroupBy(
item => item.type.id, // the group key
item => new Dictionary<int, bool>() {{ item.id, item.active }}, // the transformed elements in the group
(id, items) => new Tuple<int, List<Dictionary<int, bool>>>(id, items.ToList()) // transformation of grouping result to the final desired format
).ToList();
// check correctness
foreach (var entry in result) {
Console.Write(entry.Item1);
foreach (var dict in entry.Item2) {
foreach (var kvp in dict)
Console.WriteLine("\t\t" + kvp.Key + "\t" + kvp.Value);
}
}
And this is how it works:
o is the data model, represented using anonymous types. You can obviously use a strongly typed model here, if you already have it;
on o we apply the four-argument version of GroupBy, described in detail in the official docs from Microsoft. Basically:
the first lambda expression selects the group key;
the second lambda defines the elements that are part of each group;
the third lambda transforms each (group key, enumeration of group elements) into the Tuple<int, List<Dictionary<int, bool>>> format;
at the end we call ToList() to compute the result and store it as a list of tuples.
the last part prints the result (did not spend much time prettifying it, but it does its job validating the code).
I have a Groovy map Map<String, List<String>>. I need to go through each String list, remove those meet a condition (for example length > 3). If all elements removed from the list, remove the key from the map.
For example
{
"1" : ["1", "22,", "333", "4444"],
"2" : ["2", "2222"],
"4" : ["444444"]
}
becomes
{
"1" : ["1", "22,", "333"],
"2" : ["2"],
}
If there's any easy inplace method can do it.
Try this:
m = [
"1" : ["1", "22,", "333", "4444"],
"2" : ["2", "2222"],
"4" : ["444444"]
]
m.each {String k, List v ->
v.removeAll { it.length() > 3}
if (m[k].isEmpty()) {
m.remove(k)
}
}
m.each { k, v -> println "${k} : ${v}"}
An alternative to #ou_ryperd's answer that doesn't mutate the original map is:
def m = [
"1" : ["1", "22", "333", "4444"],
"2" : ["2", "2222"],
"4" : ["444444"]
]
def newMap = m.collectEntries { k, v -> [k, v.findAll { it.length() < 4 }] }
.findAll { k, v -> v.size() > 0 }
In Aerospike, how can I add a new key/value pair in nested object stored in bins of type map?
For ex,
I have a bins of type map against which I need to store below key/value pairs.
{
"a" : "apple",
"b" : "ball",
"c" : { "d" : "dog", "e" : "elephant" },
"f" : { "g" : { "h" : "horse" } },
"i" : { "j" : "jackal", "k" : { "l" : "lion", "m" : "monkey" } }
}
Now, I want to update an existing nested object against key "k" to add one more key value pair like below.
"k" : { "l" : "lion", "m" : "monkey", "n" : "nest" }
Final result should be like below.
{
"a" : "apple",
"b" : "ball",
"c" : { "d" : "dog", "e" : "elephant" },
"f" : { "g" : { "h" : "horse" } },
"i" : { "j" : "jackal", "k" : { "l" : "lion", "m" : "monkey", "n" : "nest" } }
}
Any suggestions on how to achieve this?
It's a NodeJS (10.6.0) application & I'm using NodeJS aerospike client (3.6.1) to interact with Aerospike (4.3.0.7).
Updates on nested CDT maps and lists are possible now, using Aerospike server version 4.6 or later and Aerospike Node.js client version 3.12 or later. That update introduced the withContext() function on list and map operations that lets you specify the context in which the list/map operation is to be executed. You can find more information in the documentation for the new CdtContext class.
Here is how you would perform the update given in your example:
const Aerospike = require('aerospike')
const maps = Aerospike.maps
Aerospike.connect().then(async (client) => {
const key = new Aerospike.Key('test', 'test', 'test')
const map = {
"a" : "apple",
"b" : "ball",
"c" : { "d" : "dog", "e" : "elephant" },
"f" : { "g" : { "h" : "horse" } },
"i" : { "j" : "jackal", "k" : { "l" : "lion", "m" : "monkey" } }
}
console.log('BEFORE:', map)
await client.put(key, map)
await client.operate(key, [
maps.put('i', 'n', 'nest')
.withContext((ctx) => ctx.addMapKey('k'))
])
const record = await client.get(key)
console.log('AFTER:', record.bins)
client.close()
}).catch((error) => {
console.error(error)
if (error.client) error.client.close()
})
Here is what you would get, when you run the example:
$ node nested-map-update-example.js
BEFORE: {
a: 'apple',
b: 'ball',
c: { d: 'dog', e: 'elephant' },
f: { g: { h: 'horse' } },
i: { j: 'jackal', k: { l: 'lion', m: 'monkey' } }
}
AFTER: {
a: 'apple',
b: 'ball',
c: { d: 'dog', e: 'elephant' },
f: { g: { h: 'horse' } },
i: { j: 'jackal', k: { l: 'lion', m: 'monkey', n: 'nest' } }
}
You will have to update the full value for the key "i".
Can I return something like:
{
"c/12313" = 1,
"c/24223" = 2,
"c/43423" = 3,
...
}
from an AQL query? The idea is something like (this non-working code):
for c in my_collection
return { c._id : c.sortOrder }
where sortOrder is some property on my documents.
Yes, it is possible to have dynamic attribute names:
LET key = "foo"
LET value = "bar"
RETURN { [ key ]: value } // { "foo": "bar" }
An expression to compute the attribute key has to be wrapped in [ square brackets ], like in JavaScript.
This doesn't return quite the desired result however:
FOR c IN my_collection
RETURN { [ c._id ]: c.sortOrder }
[
{ "c/12313": 1 },
{ "c/24223": 2 },
{ "c/43423": 3 },
...
]
To not return separate objects for every key, MERGE() and a subquery are required:
RETURN MERGE(
FOR c IN my_collection
RETURN { [ c._id ]: c.sortOrder }
)
[
{
"c/12313": 1,
"c/24223": 2,
"c/43423": 3,
...
}
]