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);
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>
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/
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
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] }