Compare objects containing arrays - javascript

I have two JS objects which contain some arrays. I'd like to compare the two objects and create a third object, containing arrays only unique to secondObj.
They look like this:
firstObj : {
Jim_Array : [...],
Joe_Array : [...],
Bill_Array : [...]
}
secondObj : {
Bill_Array : [...],
Sam_Array : [...],
Kate_Array : [...],
Jim_Array : [...],
Joe_Array : [...]
}
I'd like to compare the two objects and end up with the following:
thirdObj : {
Sam_Array : [...],
Kate_Array : [...]
}

You can try something like following
var thirdObj = {};
for (var key in secondObj) {
if(!firstObj.hasOwnProperty(key)) {
// In case you need to compare the array additional check will come here
thirdObj[key] = secondObj[key];
}
}
Another way
var thirdObj = {};
for (var key in secondObj) {
if(firstObj[key] === undefined) {
// In case you need to compare the array additional check will come here
thirdObj[key] = secondObj[key];
}
}

You can use Object.keys() with reduce() and check if firstObj has property of secondObj with hasOwnProperty(), if not add to new object.
var firstObj = {Jim_Array : ['...'], Joe_Array : ['...'], Bill_Array : ['...']}
var secondObj = {Bill_Array : ['...'], Sam_Array : ['...'], Kate_Array : ['...'], Jim_Array : ['...'], Joe_Array : ['...']}
var result = Object.keys(secondObj).reduce(function(o, e) {
if(!firstObj.hasOwnProperty(e)) o[e] = secondObj[e];
return o;
}, {});
console.log(result)

A solution using underscore:
var result = _.pick(secondObj, _.difference( _.keys(secondObj), _.keys(firstObj)));

Related

override forEach to iterate over an object attribute

I have currently an object which contains a array on which I can iterate.
====== First Step =====
Iterate over an object's attribute instead of the object itself
I am wondering if there's a way to use :
const obj = new YMap();
obj.forEach(...);
instead of
const obj = new YMap();
obj.map.forEach();
EDIT : From VLAZ Comment, I can add this :
this.forEach = function(f) { this.maps.forEach(f);}
In my constructor so my forEach iterate over the maps attribute of my
object and not over my object itself.
===== Second Step =====
Avoid forEach imbrication to parse an object attribute of type Array of Map/List/Array
By extends, if I add a little more complexity on my object so it doesn't have an array but an array of list, is there a way to do :
const obj = new YMap();
obj.forEach(...);
instead of
const obj = new YMap();
obj.maps.foreach( function(map) {
map.forEach( function(item) {
...
}
});
To explain it differently, I wonder if there's a way that exist that allow me to have this data structure :
{
maps : [
[ 'A', 'B' ],
[ 'C', 'D' ],
[ 'E', 'F' ]
]
}
Where I could use the code :
obj.forEach(function(item) { console.log(item) });
that would output :
A B C D E F
without having to iterate over the array of array and then iterate on the items of each array using an imbricated forEach
My object looks like the following :
function YMap() {
this.maps = [new HashMap()];
Object.defineProperty(YMap.prototype, 'length', {get: function() {
...
}});
}
YMap.prototype.add = function() {...}
YMap.prototype.get = function() {...}
[...]
module.exports = YMap;
you can create custom iterable to loop onto object. I have created one using class based approach with help of Symbol.iterator property.
class YMap {
constructor() {
this.maps = [];
}
[Symbol.iterator]() {
let index = 0;
const that = this;
return {
next() {
let value = undefined;
let done = true;
if (index < that.maps.length) {
value = [...that.maps[index++]].join(" ")
done = false;
}
return {
value,
done
};
}
};
}
add(item) {
this.maps.push(item);
}
}
const obj = new YMap();
obj.add([23, 21]);
obj.add([25, 29]);
for (let c of obj) {
console.log(c, );
}

Find Name of Array obj from Json

Here I want to read key name of obj.
Like "CIRTGroupBox1", "CIRTGroupBox2"
Try this :
var arr = [{
'CIRTGroupBox1': ''
}, {
'CIRTGroupBox2': ''
}, {
'CIRTGroupBox3': ''
}];
// Using array.map() method
var usingMapKeys = arr.map((obj) => Object.keys(obj)[0]);
// Using Object.entries() method
var usingEnteriesKeys = arr.map((obj) => Object.entries(obj)[0][0]);
console.log(usingMapKeys);
console.log(usingEnteriesKeys);
is it?
var x = {
"ob1": "value",
"ob2": {
"ob21": "value"
}
};
var keys = Object.keys(x);
console.log(keys);
You can do that using Object.keys method in JS like below
var keys = Object.keys(groupBoxesTemp);
This will return string array and each item in it is the key of this object.
If you want to read values pertaining those 2 keys, you can do like below using the for-in loop:
for(item in groupBoxesTemp){
console.log('key is: ', item);
console.log('value is: ', groupBoxesTemp[item]);
}
Based on your screenshot, temp is an array of objects which has 3 objects in it. You can do that too like below:
temp.forEach(function(item, index){
//key for all objects in the array will be logged.
console.log( Object.keys(item) );
});

simplifying a nested javascript object

I have an object that looks like this:
var someUglyObject =
{
"1-1" : {foo1: "foo1-1Value", bar1: "bar1-1value"},
"1-2" : {foo2: "foo1-2Value", bar2: "bar1-2value"},
"2-1" : {foo2: "foo2-1Value", bar2: "bar2-1value"},
"2-2" : {foo2: "foo2-2Value", bar2: "bar2-2value"}
}
I need to simplify the nested object above and convert into a simpler object after some processing (concatenation) like below:
var myObj = {
"1": { propsTogether : "foo1-1Valuebar1-1valuefoo1-2Valuebar1-2value"},
"2": { propsTogether : "foo2-1Valuebar2-1valuefoo2-2Valuebar2-2value" }
}
My plan is to interate through the keys like this, but not sure how to group the props together based on the first char of the key , i.e. for a key with value of '2-1' - 2 should be the new key.
var myObj= {};
Object.keys(someUglyObject).forEach(function(key) {
}
You can use Object.keys and reudce
Here idea is
First get the keys out of object.
Sort them // Object don't have order
Now split key on - and use first element as key on op object.
Use object.values and join them in desired format and place it on respective key
var obj = {'1-1' : {foo1: "foo1-1Value", bar1: "bar1-1value"},'1-2' : {foo2: "foo1-2Value", bar2: "bar1-2value"},'2-1' : {foo2: "foo2-1Value", bar2: "bar2-1value"},'2-2' : {foo2: "foo2-2Value", bar2: "bar2-2value"}}
let op = Object.keys(obj).sort().reduce((op,inp)=>{
let key = inp.split('-',1)[0]
op[key] = op[key] || {props:''}
op[key].props = op[key].props + Object.values(obj[inp]).join('')
return op
},{})
console.log(op)

Jquery Array key values with 2d array

I need to make an array that looks like this:
Array = [A:{key:value,key:value},B:{key:value,key:value}]
But I have to add elements dynamically and I need to access them, how can I do this? ... Thanks For helping
Since arrays resize automatically, you could do something pretty simple, like this (a and b are your row and column 'coordinates', respectively):
var myArray = [];
function save(a, b, value) {
var row = myArray[a];
if (!row) row = [];
row[b] = value;
myArray[a] = row;
};
function retrieve(a, b) {
var row = myArray[a];
return row ? row[b] : null;
};
This will create what I think you want :
var arr = [
{
'A' : [
{ 'key1' : 'value1' },
{ 'key2' : 'value2' }
]
},
{
'B' : [
{ 'key1' : 'value1' },
{ 'key2' : 'value2' }
]
}
];
Explanation : Here, 'arr' is basically an array of objects with 2 objects with keys 'A'/'B' and values as array of 2 more objects. (It's a little confusing)

How to break up an object with a string of values to create a new array of objects?

I was working on a solution to another question posed, and I came up with a solution, but I'm convinced that there's a more elegant way to do it. Let's say that you have an object where all of the values are a string of values separate by commas, like this:
{ "action" : "goto,goto", "target" : "http://www.google.com,http://www.cnn.com" }
But, you'd like to separate the values and break up the object into an array of objects, like this:
[
{ "action" : "goto", "target" : "http://www.google.com" },
{ "action" : "goto", "target" : "http://www.cnn.com" }
]
Here's what my solution was:
var actions = obj.action.split(',');
var targets = obj.target.split(',');
// combined the actions and targets arrays
var combinedData = _.zip(actions, targets);
// go through the combinedData array and create an object with the correct keys
var commandList = _.map(combinedData, function(value) {
return _.object(["action", "target"], value)
});
This does what I want and doesn't look terrible, but is there a slicker way of accomplishing this?
Functional style is great. Here's a more direct approach.
var newObjects = [];
for(var k in o) {
var vals = o[k].split(',');
for(var i = 0, len = vals.length; i < len; i++) {
newObjects[i] = newObjects[i] || {};
newObjects[i][k] = vals[i];
}
}
I wouldn't worry too much about the implementation until you come up with a nice, compact, semantic name for this operation. Any ideas?
So, I did a little refactoring of my code to create a more functional and cleaner looking answer:
var obj = { "action" : "goto,goto", "target" : "http://www.google.com,http://www.cnn.com" }
// separate and split the values form the object
function separate(obj) {
return _.map( _.values( obj ), function(value) {
return value.split(',');
});
}
// returns [[ "goto", "goto"], ["http://www.google.com", "http://www.cnn.com"]]
// call separate and recombine the values with zip
function separateAndRecombine(obj) {
return _.zip.apply(_, separate(obj));
}
// returns [[ "goto", "http://www.google.com"], ["goto", "http://www.cnn.com"]]
// accept an object that has properties with a string of values
// separated by commas, and separate the values to create an array of objects
function unwind(obj) {
return _.map( separateAndRecombine(obj), function(value) {
return _.object(_.keys(obj), value)
});
};
/* returns:
[{ "action" : "goto", "target" : "http://www.google.com" },
{ "action" : "goto", "target" : "http://www.cnn.com" }] */
Now, unwind() will take an object with any number of properties or values and 'unwind' all of the existing properties.

Categories