Union of 2 objects with Lodash? - lodash

I have 2 objects:
var obj1 = { a:1, b:2, c:3 };
var obj2 = { a:4, c:5, d:6 };
How could I get the union of these 2 objects with lodash? I expect the result to be:
{ a:4, c:5 }

Here is a one-line and readable snippet:
_.pick(obj2, _.intersection(_.keys(obj1), _.keys(obj2)))
// {a: 4, c: 5}
jsfiddle: http://jsfiddle.net/ze8g0p22/

Related

How to extract second level keys out of two level map using lodash

I have a data structure like this
{
'a' : { 'aa' : { b: 1, c: 2}},
'b' : { 'bb' : { c: 3, d: 4}},
'c' : { 'cc' : { c: 3, d: 4}}
}
I'd like to map it using lodash into a flat structure like this:
{
'aa' : { b: 1, c: 2}},
'bb' : { c: 3, d: 4}},
'cc' : { c: 3, d: 4}},
}
I can do it using a side effect based approach with the code like this:
const flattened = {};
_(state.values)
.map(e => _.forEach(e, (e, k) => flattened[k] = e))
.value();
It does the job, but I am looking for a nicer pure functional way to do this.
Get the values of the original object, and merge them into a new object:
const obj = {
'a' : { 'aa' : { b: 1, c: 2}},
'b' : { 'bb' : { c: 3, d: 4}},
'c' : { 'cc' : { c: 3, d: 4}}
}
const result = _.merge({}, ..._.values(obj))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

How to merge objects with Lodash, but replace arrays values?

I'm trying to replace arrays of an old object with values from a new object which has arrays... I guess it will make sense when you see an example and desire result:
https://jsfiddle.net/redlive/9coq7dmu/
const oldValues = {
a: 1,
b: [2, 21, 22, 23],
c: {
d: 3,
e: 4,
f: [5, 6, 7]
}
};
const updatedValues = {
b: [],
c: {
f: [8]
}
}
const result = _.merge( oldValues, updatedValues );
console.log(result);
/* Desire result:
{
a: 1,
b: [],
c: {
d: 3,
e: 4,
f: [8]
}
}
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
Use _.mergeWith(), and if the 2nd value is an array, return it. If not return undefined, and let merge handle it:
const oldValues = {"a":1,"b":[2,21,22,23],"c":{"d":3,"e":4,"f":[5,6,7]}};
const updatedValues = {"b":[],"c":{"f":[8]}};
const result = _.mergeWith(oldValues, updatedValues, (a, b) =>
_.isArray(b) ? b : undefined
);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>

Reducing to list of object from object key and value

Given a previous Ramda groupBy to
{
'2018-Q4': 2,
'2019-Q1': 5
}
How can I map this to
[
{'quarter': '2018-Q4', 'value': 2},
{'quarter': '2019-Q1', 'value': 5},
]
Convert to pairs and then zipObj with the field names:
const { pipe, toPairs, map, zipObj } = R
const fn = pipe(
toPairs,
map(zipObj(['quarter', 'value']))
)
const data = {
'2018-Q4': 2,
'2019-Q1': 5
}
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

How group and count elements by lodash

has data
items = {
0: {id:1,name:'foo'},
1: {id:2,name:'bar'},
2: {id:1,name:'foo'}
};
I wont get counted elements like this
result = {
0: {id:1,name:'foo', count:2},
1: {id:2,name:'bar', count:1}
};
lodash has function _.countBy(items, 'name') it's got {'foo': 2, 'bar':1}, i need id too.
If pure JS approach is acceptable, you can try something like this:
Logiic:
Loop over array and copy the object and add a property count and set it to 0.
Now on every iteration update this count variable.
Using above 2 steps, create a hashMap.
Now loop over hashMap again and convert it back to array.
var items = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
var temp = items.reduce(function(p,c){
var defaultValue = {
name: c.name,
id: c.id,
count: 0
};
p[c.name] = p[c.name] || defaultValue
p[c.name].count++;
return p;
}, {});
var result = [];
for( var k in temp ){
result.push(temp[k]);
}
console.log(result)

using vue.set in vuex is not updating the state

I'm trying to add an object into a nested array, and it is not working, but I've used this for other states and it works fine.
Has it got something to do with it begin a nested array?
this is the code I'm using
Vue.set(state.sections[getCurrentSection(state).index].rows[getCurrentRow(state).index].columns[getCurrentColumn(state).index].elements, 0, element)
this is the element object
var element = {
id: id,
style: {
backgroundColor: {
value: 'rgba(255,255,255,1)',
},
},
}
what am I doing wrong?
UPDATE
Another option to clone:
function hasProp(arg1, arg2) {
return Object.prototype.hasOwnProperty.call(arg1, arg2);
}
function extend(arg1, arg2) {
const keys = Object.keys(arg2);
const len = keys.length;
let i = 0;
while (i < len) {
arg1[keys[i]] = arg2[keys[i]];
i += 1;
}
if (hasProp(arg2, 'toString')) {
arg1.toString = arg2.toString;
}
if (hasProp(arg2, 'valueOf')) {
arg1.valueOf = arg2.valueOf;
}
return arg1;
}
const obj1 = {
a: 1,
b: 2,
c: { a: 1, b: 2}
};
const cloned = extend({}, obj1);
cloned.a = 9999;
console.log(obj1, cloned);
Make a deep copy of your state.sections;
Create a new object and make your modifications on it;
Replace state.sections with you new object - state.sections = Object.assign({}, newObject).
Your state and your view updated.