Reputation: 4620
I have an array called props
that contains n
number of arrays with objects and all arrays contain the same number of objects.
Each object has 4 properties : participation_enabled
, name
, pathing_enabled
, id
and these properties can have different values in the other arrays for the same property id...
My goal is to find all object properties that are different in the other arrays of objects and store them in another array called diffs
.
Let's take the following example:
[
[
{participation_enabled:"false", name:"PropEins", pathing_enabled:"true", id:"prop1"},
{participation_enabled:"false", name:"User Status", pathing_enabled:"false", id:"prop2"},
{participation_enabled:"false", name:"Initial ID", pathing_enabled:"false", id:"prop3"},
{participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"},
{participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
],
[
{participation_enabled:"false", name:"PropEins", pathing_enabled:"false", id:"prop1"},
{participation_enabled:"false", name:"Room", pathing_enabled:"false", id:"prop2"},
{participation_enabled:"false", name:"Phase", pathing_enabled:"false", id:"prop3"},
{participation_enabled:"false", name:"Custom Insight 4", pathing_enabled:"false", id:"prop4"},
{participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
],
[
{participation_enabled:"true", name:"PropEins", pathing_enabled:"true", id:"prop1"},
{participation_enabled:"true", name:"User Status", pathing_enabled:"true", id:"prop2"},
{participation_enabled:"true", name:"Trackingcode", pathing_enabled:"true", id:"prop3"},
{participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"},
{participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
]
]
For the above example the diffs
array should contain the following objects:
[
{id:"prop1", participation_enabled:["false","true"], pathing_enabled:["false","true"], index:0},
{id:"prop2", participation_enabled:["false","true"], name:["User Status","Room"], participation_enabled:["false","true"], pathing_enabled:["false","true"], index:1},
{id:"prop3", participation_enabled:["false","true"], name:["Initial ID","Phase","Trackingcode"], participation_enabled:["false","true"], pathing_enabled:["false","true"], index:2},
{id:"prop4", name:["User ID","Custom Insight 4"], pathing_enabled:["false","true"], index:3}
]
Any advice greatly appreciated.
Upvotes: 0
Views: 60
Reputation: 81
Check below code. May be this is not most optimal way but it solves the problem.
var mainArray = [
[{
participation_enabled: "false",
name: "PropEins",
pathing_enabled: "true",
id: "prop1"
}, {
participation_enabled: "false",
name: "User Status",
pathing_enabled: "false",
id: "prop2"
}, {
participation_enabled: "false",
name: "Initial ID",
pathing_enabled: "false",
id: "prop3"
}, {
participation_enabled: "false",
name: "User ID",
pathing_enabled: "false",
id: "prop4"
}, {
participation_enabled: "false",
name: "Subdomain",
pathing_enabled: "false",
id: "prop5"
}],
[{
participation_enabled: "false",
name: "PropEins",
pathing_enabled: "false",
id: "prop1"
}, {
participation_enabled: "false",
name: "Room",
pathing_enabled: "false",
id: "prop2"
}, {
participation_enabled: "false",
name: "Phase",
pathing_enabled: "false",
id: "prop3"
}, {
participation_enabled: "false",
name: "Custom Insight 4",
pathing_enabled: "false",
id: "prop4"
}, {
participation_enabled: "false",
name: "Subdomain",
pathing_enabled: "false",
id: "prop5"
}],
[{
participation_enabled: "true",
name: "PropEins",
pathing_enabled: "true",
id: "prop1"
}, {
participation_enabled: "true",
name: "User Status",
pathing_enabled: "true",
id: "prop2"
}, {
participation_enabled: "true",
name: "Trackingcode",
pathing_enabled: "true",
id: "prop3"
}, {
participation_enabled: "false",
name: "User ID",
pathing_enabled: "false",
id: "prop4"
}, {
participation_enabled: "false",
name: "Subdomain",
pathing_enabled: "false",
id: "prop5"
}]
];
var resultArray = mainArray[0];
for (var i = 0; i < mainArray.length; i++) {
var arrayTocheck = mainArray[i];
for (var outer = 0; outer < resultArray.length; outer++) {
row = resultArray[outer];
if (i == 0) {
row.participation_enabled = [];
row.name = [];
row.pathing_enabled = [];
}
for (var inner = 0; inner < resultArray.length; inner++) {
var rowtoCheck = arrayTocheck[inner];
if (row.id == rowtoCheck.id) {
if (!row.participation_enabled.includes(rowtoCheck.participation_enabled) && rowtoCheck.participation_enabled != "") {
row.participation_enabled.push(rowtoCheck.participation_enabled);
}
if (!row.name.includes(rowtoCheck.name) && rowtoCheck.name != "") {
row.name.push(rowtoCheck.name);
}
if (!row.pathing_enabled.includes(rowtoCheck.pathing_enabled) && rowtoCheck.pathing_enabled != "") {
row.pathing_enabled.push(rowtoCheck.pathing_enabled);
}
break;
}
}
resultArray[outer] = row;
}
}
console.log(resultArray);
Upvotes: 0
Reputation: 23382
A pure js example. Note that if you can be sure all properties contain strings, you could replace the indexOf
search with a object-property based approach to check for duplicates faster.
Important assumption:
var sampleData = [
[
{participation_enabled:"false", name:"PropEins", pathing_enabled:"true", id:"prop1"},
{participation_enabled:"false", name:"User Status", pathing_enabled:"false", id:"prop2"},
{participation_enabled:"false", name:"Initial ID", pathing_enabled:"false", id:"prop3"},
{participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"},
{participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
],
[
{participation_enabled:"false", name:"PropEins", pathing_enabled:"false", id:"prop1"},
{participation_enabled:"false", name:"Room", pathing_enabled:"false", id:"prop2"},
{participation_enabled:"false", name:"Phase", pathing_enabled:"false", id:"prop3"},
{participation_enabled:"false", name:"Custom Insight 4", pathing_enabled:"false", id:"prop4"},
{participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
],
[
{participation_enabled:"true", name:"PropEins", pathing_enabled:"true", id:"prop1"},
{participation_enabled:"true", name:"User Status", pathing_enabled:"true", id:"prop2"},
{participation_enabled:"true", name:"Trackingcode", pathing_enabled:"true", id:"prop3"},
{participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"},
{participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
]
];
// Reduce an array of data arrays into one array of merged objects
function dataReducer (matches, current) {
current.forEach(function(obj, i) {
if (!matches[i]) {
matches[i] = obj;
} else {
matches[i] = mergeObj(matches[i], obj);
}
});
return matches;
};
// Merge two matching objects
function mergeObj(obj1, obj2) {
Object.keys(obj1).forEach(function(key) {
if (obj1[key] !== obj2[key]) {
obj1[key] = [].concat(obj1[key]);
if (obj1[key].indexOf(obj2[key]) == -1) {
obj1[key].push(obj2[key]);
}
}
});
return obj1;
};
var result = sampleData.reduce(dataReducer, []);
console.log(result);
Upvotes: 0
Reputation: 3411
Not the most elegant way. But it works using underscore JS.
Hope this will helps you. Also add some error handling would be good idea.
EDIT Add support to use google underscore methods. Now all should work. https://sites.google.com/site/scriptsexamples/custom-methods/underscoregs#TOC-_values-Object-obj-
var a = [
[
{participation_enabled:"false", name:"PropEins", pathing_enabled:"true", id:"prop1"},
{participation_enabled:"false", name:"User Status", pathing_enabled:"false", id:"prop2"},
{participation_enabled:"false", name:"Initial ID", pathing_enabled:"false", id:"prop3"},
{participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"},
{participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
],
[
{participation_enabled:"false", name:"PropEins", pathing_enabled:"false", id:"prop1"},
{participation_enabled:"false", name:"Room", pathing_enabled:"false", id:"prop2"},
{participation_enabled:"false", name:"Phase", pathing_enabled:"false", id:"prop3"},
{participation_enabled:"false", name:"Custom Insight 4", pathing_enabled:"false", id:"prop4"},
{participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
],
[
{participation_enabled:"true", name:"PropEins", pathing_enabled:"true", id:"prop1"},
{participation_enabled:"true", name:"User Status", pathing_enabled:"true", id:"prop2"},
{participation_enabled:"true", name:"Trackingcode", pathing_enabled:"true", id:"prop3"},
{participation_enabled:"false", name:"User ID", pathing_enabled:"false", id:"prop4"},
{participation_enabled:"false", name:"Subdomain", pathing_enabled:"false", id:"prop5"}
]
];
var diff = {};
a.forEach(function(val, i){
//first just init start object
if (i == 0) {
val.forEach(function(v1, ind){
diff[v1.id] = {};
diff[v1.id].index = [ind];
for (var key in v1) {
diff[v1.id][key] = [v1[key]];
}
});
}
else {
//for all other values add them into array and remove dups
val.forEach(function(v1){
var id = v1.id;
for (var key in v1) {
diff[id][key].push(v1[key]);
}
});
}
});
//now finalize data removing all that have only unique values
for (var key in diff) {
var nested = diff[key];
var index = nested.index.pop();
for (nestedKey in nested) {
nested[nestedKey] = _.filter(nested[nestedKey], function(item, pos) {
return nested[nestedKey].indexOf(item) == pos;
});
if (nested[nestedKey].length < 2) {delete nested[nestedKey];}
}
diff[key].id = key;
diff[key].index = index
if (_.keys(diff[key]).length < 3) {delete diff[key];}
}
diff = _.values(diff);
console.log(diff);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
Upvotes: 1