Get duplicate key names json jquery - javascript

I want an array which will fetch me duplicate keys of the json
Ex:
var catalog=[
{ ip: 'ipId_1', name: '192.160.121.11' },
{ ip: 'ipId_dyn_1_0', name: '192.160.121.12' },
{ ip: 'ipId_dyn_1_1', name: '192.160.121.12' }
];
Since 192.160.121.12 is repeating, i want an array like [ipId_dyn_1_0, ipId_dyn_1_1],
Tried so far (Fiddle Demo):
var categories =[];
var dup= [];
$.each(catalog, function(index, value) {
console.log( categories+''+value.name);
if ($.inArray(value.name, categories) == -1) {
categories.push(value.name);
}else{
dup.push(value.ip);
console.log(value.ip);
}
});
console.log(categories);
console.log(dup);

var cat_inverted = {}, categories = [];
$.each(catalog, function(index, value) {
if (cat_inverted[value.name]) {
cat_inverted[value.name].push(value.ip);
} else {
cat_inverted[value.name] = [value.ip];
categories.push(value.name);
}
});
var dup = [];
for (var name in cat_inverted) {
if (cat_inverted[name].length > 1) {
$.each(cat_inverted[name], function(i, ip) {
dup.push(ip);
});
}
}

Check:
var catalog=[
{ ip: 'ipId_1', name: '192.160.121.11' },
{ ip: 'ipId_dyn_1_0', name: '192.160.121.12' },
{ ip: 'ipId_dyn_1_1', name: '192.160.121.12' }
];
var my = {};
var dup = [];
$.each(catalog, function(index, value) {
if(!!!my[value.name]) {
my[value.name] = [];
}
my[value.name].push(value.ip);
});
$.each(my, function(index, value) {
if(value.length > 1) {
$.each(my[index], function(i, val) {
dup.push(val);
});
}
});
console.log(dup);
jsfiddle

If you use this:
var catalog=[
{ ip: 'ipId_1', name: '192.160.121.11' },
{ ip: 'ipId_dyn_1_0', name: '192.160.121.12' },
{ ip: 'ipId_dyn_1_1', name: '192.160.121.12' }
];
var values = {};
$.each(catalog, function(index, data) {
var name = data.name;
if(typeof values[name] == 'undefined') values[name] = [];
values[name].push(data.ip);
});
var dupes = [];
$.each(values,function(name,indexes) {
if(indexes.length > 1)
{
dupes.push(indexes);
}
});
console.dir(dupes);
dupes will now contain an array of arrays (sets of duplicates)
Give it a run and see how it works for ya

I would use lodash.js or underscore.js for this task because of the functional approach. You are more flexible in changing your task when using this approach.
You can store your data in an variable and later easily transform them to your desired data structure.
var catalog=[
{ ip: 'ipId_1', name: '192.160.121.11' },
{ ip: 'ipId_dyn_1_0', name: '192.160.121.12' },
{ ip: 'ipId_dyn_1_1', name: '192.160.121.12' }
];
var categoriesObjectsUniqe =[];
var categories =[];
var dupObjects= [];
var dup= [];
categoriesObjectsUniqe = _.unique(catalog, 'name');
categories = _.map(categoriesObjectsUniqe, function(val) {
return val.name; })
dupObjects = _.filter(catalog, function(current) {
return arr = _.filter(catalog, function(currentInner) {
return currentInner.name === current.name; }).length > 1;
});
dup = _.map(categoriesObjUniqe, function(val) {
return val.ip; })
console.log('uniqe Objects :');
console.log(categoriesObjectsUniqe);
console.log('uniqe IPs :');
console.log(categories);
console.log('duplicate Objects :');
console.log(dupObjects);
console.log('duplicate ips :');
console.log(dup);
Here is the fiddle for that.
http://jsfiddle.net/3wHfB/94/

Related

How to convert array of object into an array of object with different format?

I'm having an array of object,in which I'm storing the billkey and billvalue as attributes. I want billkey to be the key and billvalue to be the value of that particular key.
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
}
{
billkey:"Name",
billvalue:"XYZ"
},
{
billkey:"Department",
billvalue:"Electrical"
}];
And I want to convert it into this format:
var log=[
{
Name:"ABC",
Department:"Computer"
},
{
Name:"XYZ",
Department:"Electrical"
}];
How about this simple solution. Hope it helps!
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
},
{
billkey:"Name",
billvalue:"XYZ"
},
{
billkey:"Department",
billvalue:"Electrical"
}];
var arr = [];
var finalObj = [];
for(var i in log){
var someObject = log[i];
for(var j in someObject){
arr.push(someObject[j]);
}
}
for(var k = 0; k < arr.length; k+=4){
finalObj.push({
Name: arr[k+1],
Department: arr[k+3]
});
}
console.log(finalObj);
create the result using forloop
// store the values
var logs=[];
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
},
{
billkey:"Name",
billvalue:"XYZ"
},
{
billkey:"Department",
billvalue:"Electrical"
},
];
loop the first array
for (i = 0; i < log.length; i++) {
// create empty variable for storing the values
var index = new Array();
// insert the first index value to key
index[log[i].billkey] = log[i].billvalue
// insert the second index value to key
index[log[i+1].billkey] = log[i+1].billvalue
// insert the result in to new array
logs.push(index);
// increment the i with 1
i=i+1;
}
console.log(logs);
You could use Array#reduce and use the remainder operator as witch for using either the last object or create a new one.
var log = [{ billkey: "Name", billvalue: "ABC" }, { billkey: "Department", billvalue: "Computer" }, { billkey: "Name", billvalue: "XYZ" }, { billkey: "Department", billvalue: "Electrical" }],
result = log.reduce(function (r, a, i) {
var o = {};
if (i % 2) {
r[r.length - 1][a.billkey] = a.billvalue;
} else {
o[a.billkey] = a.billvalue;
r.push(o);
};
return r;
}, []);
console.log(result);

How to Group By Json Array

I have an array and i want to apply group By column (key).
I have this.
app.groupDtData = function(data, column) {
var generatedData=[];
$.each(data,function(i,dt){
// generatedData
// if(jQuery.inArray( "John", generatedData ))
});
}
i have to push it into generatedData and check by jQuery.inArray ?
You wouldn't use inArray for that as you need an object to hold the result, not an array. Use the in operator to look for the property in the object.
You would get the column value from the item and then check if it exist in the result. If it doesn't exist, add a new array by that name. Add the item to the array and lastly return the result:
app.groupDtData = function(data, column) {
var generatedData = {};
$.each(data, function(i, dt) {
var key = dt[column];
if (!(key in generatedData)) {
generatedData[key] = [];
}
generatedData[key].push(dt);
});
return generatedData;
};
Demo:
function group(data, column) {
var generatedData = {};
$.each(data, function(i, dt) {
var key = dt[column];
if (!(key in generatedData)) {
generatedData[key] = [];
}
generatedData[key].push(dt);
});
return generatedData;
}
var g = group([
{ name: 'John', grp: '1' },
{ name: 'Elsa', grp: '2' },
{ name: 'Mandy', grp: '2' },
{ name: 'Bo', grp: '1' }
], 'grp');
document.write(JSON.stringify(g));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Filter Array based on another array

I have a list with that contains a list of objects. Each object has 4 properties on it. There is a checkbox list with the unique values of two of the properties, this helps build my filter array.
the Filter might end up looking like this:
[
{
prop: 'username',
val: ['max', 'sam']
},
{
prop: 'color',
val: ['blue', 'green']
}
]
The list of objects would look something like this:
[
{
username: 'sam',
color: 'blue'
},
{
username: 'jimmy',
color: 'blue'
},
{
username: 'sam',
color: 'black'
},
{
username: 'max',
color: 'green'
},
{
username: 'max',
color: 'blue'
}
]
The Desired Result
[
{
username: 'sam',
color: 'blue'
},
{
username: 'max',
color: 'green'
},
{
username: 'max',
color: 'blue'
}
]
I feel like I'm going down a never ending forEach rabbit hole. I'm guessing I need some sort of recursion. Currently here is what I have:
var temporary = scope.transactions;
function getFilteredTransactions() {
var filter = deviceFilterService.get();
if (filter.length > 0) {
var temp2 = [];
angular.forEach(filter, function (fil) {
//object
angular.forEach(fil.val, function (filterValue) {
//list on each object
angular.forEach(temporary, function (transaction) {
if (transaction[fil.prop] === filterValue) {
if (temp2.indexOf(transaction) === -1) {
temp2.push(transaction);
}
}
});
temporary = temp2;
});
});
$log.debug(temporary);
scope.transactions = temporary;
} else {
initialize();
}
}
This is starting to work, the second time it goes through the property for color it ends up just wanting to add the exact same transaction to the temp2 array. There has to be a better way to set this up, possibly through recursion.
If you convert the format of the first list to a dictionary, i think if should get easier.
var dict = {};
angular.forEach(source1, function(ob){
dict[ob.prop] = ob.val;
});
function getFiltered(ob){
for(var prop in ob){
if(dict[prop] && dict[prop].indexOf(ob[prop]) === -1){
return false;
}
}
return true;
};
and just call it as:
var temporary = scope.transactions.filter(getFiltered);
Demo
Basically the first part converts:
[
{
prop: 'username',
val: ['max', 'sam']
},
{
prop: 'color',
val: ['blue', 'green']
}
];
to:
{
username:['max', 'sam'],
color:['blue', 'green']
}
so that it makes the look up much easier.
You might want to change the variable names here for clarity, but this will do what you're asking for:
var values = {};
angular.forEach(startingData, function(rawData) {
angular.forEach(rawData, function(value, key) {
if (angular.isUndefined(values[key])) {
values[key] = [];
}
if (values[key].indexOf(value) === -1) {
values[key].push(value);
}
})
});
var result = [];
angular.forEach(values, function(value, key) {
result.push({prop: key, val: value})
});
You can simply iterate each key of the data the needs filtering, find the appropriate filter per that key, and check the value against the filter values:
$scope.transactions = $scope.transactions.filter(isItemValidFilter);
function isItemValidFilter(item) {
var filters = deviceFilterService.get();
//For each property in the data, get the correct filter from the list of filters
var totalConditions = Object.keys(item).length;
var correctConditions = 0;
for (var filterKey in item) {
var correctFilters = filters.filter(function(dataFilter) {
return dataFilter.prop == filterKey
});
if (correctFilters.length) {
//Ill assume only 1 filter, so just use the 0 index
var correctFilter = correctFilters[0];
var conditions = correctFilter.val;
if (conditions && conditions.length) {
//check the values!
if (conditions.indexOf(item[filterKey]) > -1) {
correctConditions++;
}
}
}
}
return correctConditions === totalConditions;
}
Demo: http://jsfiddle.net/Lz32hka5/1/
Try:
var temp2 = [], matched;
angular.forEach(temporary, function(item){
matched = true;
angular.forEach(Object.keys(item), function(key){
angular.forEach(filter, function(filter){
filter.prop == key && filter.val.indexOf(item[key]) == -1 && (matched = false);
});
});
matched && temp2.push(item);
});
console.log(temp2)
temporary is the list of objects, filter: your filters
Demo: http://jsfiddle.net/wZVanG/7wnae850/

Get string representation of JavaScript object

I have a object like so:
$scope.query = {
filter: {
column: {
productName: 'Some Product',
price: 29.95,
...
},
table: {
productType: 'GM',
categoryId: 1,
...
}
}
};
How do I get a string that represents the whole object in dot notation? e.g.
query.filter.table.productType
To clarify, I am using this string value as a key to store a key/value pair in localStorage.
I am using angular to $wacth each property on the object for a change. Since you can't watch an object and know which property changed with watching all, I need to get creative and store each property in a key/value pair.
You can do it recursively, and produces "key" in an array.
var obj = {
query: {
filter: {
table: {
productType: 'GM'
}
}
}
};
var stringify = function (e) {
var rs = [];
for (var k in e) {
if (e.hasOwnProperty(k)) {
if (typeof e[k] == 'object') {
var l = stringify(e[k]);
for (var i = 0; i < l.length; i++) {
rs.push(k + '.' + l[i]);
}
} else {
rs.push(k);
}
}
}
return rs;
}
console.log(stringify(obj));
outputs:
["query.filter.table.productType"]
fiddle
Demo
Before Ques Edit
var $scope = {
query: {
filter: {
table: {
productType: 'GM'
}
}
}
};
var k = JSON.stringify($scope)
//output "{"query":{"filter":{"table":{"productType":"GM"}}}}"
k.match(/\w+(?=\"\:)/g).join('.')
//output"query.filter.table.productType"
Edit
Updated Demo
If OP has no issue with the position of child elements
var $scope = {}
$scope.query = {
filter: {
column: {
productName: 'Some Product',
price: 29.95
},
table: {
productType: 'GM',
categoryId: 1,
}
}
};
k=JSON.stringify($scope)
{"query":{"filter":{"column":{"productName":"Some Product","price":29.95},"table":{"productType":"GM","categoryId":1}}}}
k.match(/\w+(?=\"\:)/g).join('.')
"query.filter.column.productName.price.table.productType.categoryId"
By iterating the properties into an array recursively you could create a hierarchical structure that represents the data in the object. From here you could parse the results out as you wish.
var scope = {
query: {
filter: {
column: {
productName: 'Some Product',
price: 29.95
},
table: {
productType: 'GM',
categoryId: 1
}
}
}
};
function buildProps(subject) {
var result = [];
for (var key in subject) {
if (subject.hasOwnProperty(key)) {
if (typeof subject[key] == "object") {
result.push(key, buildProps(subject[key]));
} else {
result.push(key);
}
}
}
return result;
}
function stringify(input) {
var result = [];
for (var i = 0; i < input.length; i++) {
if (typeof input[i] == "string") {
result.push(input[i]);
} else {
result = result.concat(stringify(input[i]));
}
}
return result.join('.');
}
console.log(buildProps(scope));
console.log(stringify(buildProps(scope)));
Parse out the strings in the resulting array/sub-arrays, format it any way you like.
In my simple example I just list them in order:
query.filter.column.productName.price.table.productType.categoryId

How to merge objects using javascript

I am trying to create a json object similar to the below:
[
{
"name":"aaa_aaaurf",
"region":"F&R",
"checkins":[[1,0],[2,0],[3,0],[4,3],[5,0],[6,0],[7,0],[8,3],[9,0],[10,0],[11,0],[12,0]],
"teamsize":[[1,0],[2,0],[3,0],[4,3],[5,0],[6,0],[7,0],[8,1],[9,0],[10,0],[11,0],[12,0]],
"Checkintimes":[[1,0],[2,0],[3,0],[4,184],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0]]
},
{
"name":"aaa_accessservices",
"region":"F&R",
"checkins":[[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,27],[12,12]],
"teamsize":[[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,11],[12,11]],
"Checkintimes":[[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,10],[12,12]]
}]
I have written the script using d3 but the object is getting overwritten with the latest one.How to merge the object array to get the json?
Following is the code:
var dataset;
var teamsize={};
var repository;
var sbu;
var index=0;
var teamsizearray = [];
var checkinsarray = [];
var checkintimesarray = [];
var ConsData = {};
var MergeData = {};
var tempData={};
d3.csv("bubblechart.csv", function(data, error) {
dataset = data;
alert(dataset.length);
//alert(error);
for(var x=0;x<dataset.length;x++)
{
if (x==0)
{
repository = dataset[0].repository;
}
if (dataset[x].repository!= repository)
{
if ((x > 0 ) || (x==dataset.length))
{
index = 1;
ConsData["name"] = repository;
ConsData["region"] = sbu;
ConsData["checkins"] = checkinsarray;
ConsData["teamsize"] = teamsizearray;
ConsData["Checkintimes"] = checkintimesarray;
tempData=ConsData;
jQuery.extend(MergeData, tempData);
teamsizearray = [];
checkinsarray = [];
checkintimesarray = [];
repository = dataset[x].repository;
sbu = dataset[x].BusinessUnit
checkinsarray.push([index, dataset[x].AvgCheckinCount]);
teamsizearray.push([index, dataset[x].TeamSize]);
checkintimesarray.push([index, dataset[x].MeanBuildTimeHrs]);
}
}
else
{
if (x ==0)
{
index=1;
}
else
{
index=index+1;
}
repository = dataset[x].repository;
sbu = dataset[x].BusinessUnit
checkinsarray.push([index, dataset[x].AvgCheckinCount]);
teamsizearray.push([index, dataset[x].TeamSize]);
checkintimesarray.push([index, dataset[x].MeanBuildTimeHrs]);
}
}
console.log(JSON.stringify(MergeData));
});
Following is the the csv data.
aaa_aaaurf,1,2013,0,0,0,Financial&Risk
aaa_aaaurf,2,2013,0,0,0,Financial&Risk
aaa_aaaurf,3,2013,0,0,0,Financial&Risk
cCG_tzz,1,2013,5,3,100,Financial&Risk
cCG_tzz,2,2013,8,5,80,Financial&Risk
aCG_txz,1,2013,12,3,70,Financial&Risk
GCG_txz,1,2013,21,3,50,Financial&Risk
GCG_txz,2,2013,12,3,70,Financial&Risk
Can you use lodash?
var names = {
'characters': [
{ 'name': 'barney' },
{ 'name': 'fred' }
]
};
var ages = {
'characters': [
{ 'age': 36 },
{ 'age': 40 }
]
};
_.merge(names, ages);
// → { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
var food = {
'fruits': ['apple'],
'vegetables': ['beet']
};
var otherFood = {
'fruits': ['banana'],
'vegetables': ['carrot']
};
_.merge(food, otherFood, function(a, b) {
return _.isArray(a) ? a.concat(b) : undefined;
});
// → { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }

Categories