How to obtain an object specific value? - javascript

I get the following object from a php file:
[
{"val1":"A","val2":"TA","val3":"5"},
{"val1":"A","val2":"TB","val3":"3"},
{"val1":"A","val2":"TC","val3":"2"}
]
I tried doing things like:
{label: {data:'val1'} }
{label: {data:'val1'[0]} }
{label: {data:['val1'][0]} }
But so far no luck to obtain the value I want.
This is the part of my code that deals with the data from the object:
var containerD1 = document.getElementById('tabD1');
var hotD1 = new Handsontable(containerD1, {
rowHeaders: true,
colHeaders: true,
columns: [
{type:'text', data: 'val2', readOnly:true},
{type:'text', data: 'val3', readOnly:true},
],
nestedHeaders: [
[{label: {data:'val1'}, colspan: 2}],
['Val2','Val3']
]
});
Since val1 value is dynamic, I can't set it as I have done for val2 and val3
So what I want to achieve is obtaining the value from val1 to be able to use it in the nestedHeaders part as the title for my table, since this value is repeated trough my object, it doesn't matter from which one I take it.
So far what I obtain is a table like this
+------+------+
| object |
+------+------+
| val2 | val3 |
+------+------+
| TA | 5 |
| TB | 3 |
| TC | 1 |
+------+------+
In the object part, in my table it says this [object Object].
So I'm guessing it's actually being read as an object instead of the value I want.
And I'm trying to get something like this:
+------+------+
| A |
+------+------+
| val2 | val3 |
+------+------+
| TA | 5 |
| TB | 3 |
| TC | 1 |
+------+------+

Code snippet to get the value of val1
{ label: { data: data[0].val1 } }

I'm not sure if I understand you correctly. If you want to obtain the value of val1 property in your objects, I would do this (since you say it doesn't matter from which element of the array you take it):
const data = [
{"val1":"A","val2":"TA","val3":"5"},
{"val1":"A","val2":"TB","val3":"3"},
{"val1":"A","val2":"TC","val3":"2"}
]
console.log(data[0]["val1"])
Alternatively, you could write:
console.log(data[0].val1) instead of the last line of code.

Related

How to manipulate json data with AND, OR and NOT operators to get possible conditions

I have a JSON Object, which have pre and post filters for different payment types. I have to compute the possible combinations of inputs which can be passed for another API.
JSON Example:
{
"refund": {
"preFilters": {
"type": [ "1" ]
},
"postFilters": {
"flag2": [ "123", "678" ],
"flag5": [ "907", "8752" ]
}
}
Here, I need to get possible conditions that can be computed through AND, OR and NOT operators. Example, in this json I have to get the below 16 combinations:
1= type & (flag2 & flag5),
2= type & (flag2 | flag5),
3= type & (!flag2 & !flag5),
4= type & (!flag2 & flag5),
5= type & (flag2 | !flag5),
6= type & (!flag2 | !flag5),
7= type & (!flag2 | flag5),
8= type & (flag2 | !flag5),
9= type | (flag2 & flag5),
10=type | (flag2 | flag5),
11=type | (!flag2 & !flag5),
12=type | (!flag2 & flag5),
13=type | (flag2 & !flag5),
14=type | (!flag2 | !flag5),
15=type | (!flag2 | flag5),
16=type | (flag2 | !flag5)
And, also the type in preFilters and flag values in postFilters can have multiple values.I need to derive these set of possible conditions using And, Or and Not operators with values from pre and post filters.
Any advice or solution will be appreciated. Thanks
Make an array of functions matching the structure of your list of algorithms, then you can iterate the arrays in your data and apply those functions
const algos = [
(type, flag2, flag5) => type & (flag2 & flag5),
(type, flag2, flag5) => type & (flag2 | flag5),
(type, flag2, flag5) => type & (~flag2 & ~flag5)
// etc
];
const data = {
"refund": {
"preFilters": {
"type": [ "1" ]
},
"postFilters": {
"flag2": [ "123", "678" ],
"flag5": [ "907", "8752" ]
}
}
};
let output = [];
data.refund.preFilters.type.forEach(t => {
data.refund.postFilters.flag2.forEach(f2 => {
data.refund.postFilters.flag5.forEach(f5 => {
output.push({
type: t,
flag2: f2,
flag5: f5,
results: algos.map(algo => algo(t, f2, f5))
});
});
});
});
console.log(output);

How to combine a single array of objects based on multiple properties

Utilizing javascript, I have an array of objects that looks like this:
id | date | store | type | txn | failed
------------------------------------------------
1 | 10-02-18 | 32 | short | 4 | false
2 | 10-02-18 | 32 | long | null | true
3 | 10-03-18 | 32 | short | 7 | false
4 | 10-03-18 | 32 | long | 10 | false
I want to be able to transform this array into something that looks like this:
[
{
date: 10-02-18,
store: 32,
short: {
txn: 4,
failed: false,
},
long: {
txn: null,
failed: true,
},
},
{
date: 10-03-18,
store: 32,
short: {
txn: 7,
failed: false,
},
long: {
txn: 10,
failed: true,
},
}
]
You can see I would like to combine the "type", "txn" and "failed" properties with row that have the same "date" and "storeId", adding the "type" as a property and "txn" and "failed" as child properties of the "type". The "id" property could be ignored in the new array.
I use lodash quite a bit but that isn't a requirement for this. I'm just struggling to wrap my head around how to do this transformation.
You basically just need to create an object with keys that represent something unique to the groups you want. You could make keys that are concatenations of store_date for example and the object will only have one of those and it will be quick to get if you have the store and date. You can build an object like this with reduce. Once you have the object, you can simply call Object.values to get the array of values. For example:
let arr = [
{id:1, date: "10-02-18",store: 32, type: "short", tx: 4, failed: false},
{id:2, date: "10-02-18",store: 32, type: "long", tx: null, failed: true},
{id:3, date: "10-03-18",store: 32, type: "short", tx: 7, failed: false},
{id:4, date: "10-03-18",store: 32, type: "long ", tx: 10, failed: false}
]
let obj = arr.reduce((obj, {id, date, store, type, tx, failed}) => {
// make a unique key
key = `${date}_${store}`
// if we haven't seen this key add it with the outline of the object
if(!obj[key]) obj[key] = {date, store}
// add specific type to either the found obj or the new one
obj[key][type] = {tx, failed}
return obj
}, {})
// obj is an object keyed to date_store
// get just the values
console.log(Object.values(obj))

Javascript object when setting property all properties with same name are set

I've only recently started working with javascript and NodeJs.
I'm facing a simple problem that I am finding difficult to find answers to online.
I'm initialising an object holding a number of products each product then has a price and availability. When I try and set the price of one product, it sets the price of all the products rather than just the one i wanted to set. What am I doing wrong?
var ProdStruct = {
'price' : 0,
'available' : 0,
};
var Prods = {
'1' : ProdStruct,
'2' : ProdStruct,
'3' : ProdStruct,
'4' : ProdStruct,
'5' : ProdStruct,
'6' : ProdStruct,
'6' : ProdStruct,
'7' : ProdStruct
};
Prods['6']['price'] = 99;
console.log(Prods);
The Output:
{ '1': { price: 99, available: 0 },
'2': { price: 99, available: 0 },
'3': { price: 99, available: 0 },
'4': { price: 99, available: 0 },
'5': { price: 99, available: 0 },
'6': { price: 99, available: 0 },
'7': { price: 99, available: 0 } }
You have only one ProdStruct object, which you're referring to seven times. That is, you have something like this in memory:
+−−−−−−−−−−−−−−+
ProdStruct−−−−−−−−−−−−−−+−+−+−+−+−+−+−−>| (object) |
/ / / / / / / +−−−−−−−−−−−−−−+
| | | | | | | | price: 0 |
| | | | | | | | available: 0 |
| | | | | | | +−−−−−−−−−−−−−−+
+−−−−−−−−−−+ | | | | | | |
Prods−−−>| (object) | | | | | | | |
+−−−−−−−−−−+ | | | | | | |
| 1 |−−+ | | | | | |
| 2 |−−−−+ | | | | |
| 3 |−−−−−−+ | | | |
| 4 |−−−−−−−−+ | | |
| 5 |−−−−−−−−−−+ | |
| 6 |−−−−−−−−−−−−+ |
| 7 |−−−−−−−−−−−−−−+
+−−−−−−−−−−+
Modifying the state of that one object (changing price) modifies its state; doesn't matter which of the seven references you use to get to it to make the change or to look at the result, it's just one object.
You'd need to make a copy of the object to get the result you expect. One way is to use Object.assign:
var ProdStruct = {
'price' : 0,
'available' : 0,
};
var Prods = {
'1' : Object.assign({}, ProdStruct),
'2' : Object.assign({}, ProdStruct),
'3' : Object.assign({}, ProdStruct),
'4' : Object.assign({}, ProdStruct),
'5' : Object.assign({}, ProdStruct),
'6' : Object.assign({}, ProdStruct),
'6' : Object.assign({}, ProdStruct),
'7' : Object.assign({}, ProdStruct)
};
Prods['6']['price'] = 99;
console.log(Prods);
.as-console-wrapper {
max-height: 100% !important;
}
...but I think in your case I'd probably just have a constructor function:
function Prod() {
this.price = 0;
this.available = 0;
}
var Prods = {
'1' : new Prod(),
'2' : new Prod(),
'3' : new Prod(),
'4' : new Prod(),
'5' : new Prod(),
'6' : new Prod(),
'6' : new Prod(),
'7' : new Prod()
};
Prods['6']['price'] = 99;
console.log(Prods);
.as-console-wrapper {
max-height: 100% !important;
}
As Rick mentioned in a comment, you could have that constructor accept parameters:
function Prod(price, available) {
this.price = price || 0;
this.available = available || 0;
}
In that, if you don't provide price or available, it will have the value undefined, and that code uses the common idiom something || default to use 0 instead of undefined, making use of what I call the curiously powerful || operator. (Beware of doing this when it's valid for something to be a falsy* value.)
In ES2015 and later, you could do those defaults in the parameter list:
function Prod(price = 0, available = 0) {
this.price = price;
this.available = available;
}
The defaults will get applied if you don't provide arguments for those parameters (or if you explicitly provide undefined for them).
* "falsy" - In JavaScript, a value that coerces to false when used as a boolean is falsy. The falsy values are 0, "", null, undefined, NaN, and of course, false. All other values are truthy.
A couple of side-notes:
In JavaScript, the overwhelming convention is to only use initially-capped names for constructor functions, not for variables referring to other things. So prodStruct and prods.
A series of things like your Prods would probably be better as an array ([]), rather than an object with number-named properties.
The quotes around a property name in an object initializer are only required if the name isn't a valid identifier or a valid integer. All of your property names are, so you could leave them off.
Although Prods['6']['price'] works, it's more simply and idiomatically written prods[6].price.

Group By - Angular JS

I have the following JSON format, and I am looking to combine the "Virtual" and "Physical" objects into one by grouping by cluster and idc
[
{
"_id": {
"cluster": 1,
"idc": "LH8",
"type": "Virtual"
},
"SumCores": 112,
"SumMemory": 384
},
{
"_id": {
"cluster": 1,
"idc": "LH8",
"type": "Physical"
},
"SumCores": 192,
"SumMemory": 768
},
{
"_id": {
"cluster": 2,
"idc": "LH8",
"type": "Virtual"
},
"SumCores": 232,
"SumMemory": 469
},
{
"_id": {
"cluster": 2,
"idc": "LH8",
"type": "Virtual"
},
"SumCores": 256,
"SumMemory": 1024
}
Currently I have all of the output to screen using ng-repeat:
<div ng-repeat="item in servers | orderBy:['idc','cluster'] "><p>IDC:{{item._id.idc}} - Cluster: {{item._id.cluster}} - Type: {{item._id.type}} - Sum Cores: {{ item.SumCores }} </p></div>
Which produces something similar to:
IDC: LH8 - Cluster: 1 - Type: Virtual - Sum Cores: 192
IDC: LH8 - Cluster: 1 - Type: Physical -Sum Cores: 112
IDC: LH8 - Cluster: 2 - Type: Virtual - Sum Cores: 256
IDC: LH8 - Cluster: 2 - Type: Physical -Sum Cores: 232
Ideally I want to group this into a table with this as the ideal format:
+---------+--------------------+--------------------+
| Cluster | LH5 | LH8 |
+---------+--------------------+--------------------+
| | Physical | Virtual | Physical | Virtual |
+---------------------------------------------------+
| 1 | Value | Value | Value | Value |
| 2 | Value | Value | Value | Value |
| 3 | Value | Value | Value | Value |
| 4 | Value | Value | Value | Value |
+---------+----------+---------+----------+---------+
Obviously there is a lot more data than in my sample and value would represent the SumCores.
I also have access to the controller if you think the change would be better made in there:
Machine.aggregate( [ { $match : { $and: [ {"idc": req.query.idc }, {"customer":req.query.customer} ] } } ,{"$group":{_id: {"cluster":"$cluster","idc":"$idc","type":"$type"},"SumCores":{"$sum":"$cores"},"SumMemory": { "$sum":"$memory" }}}, { $sort : { idc : -1, cluster: 1 } } ]).exec(function(err, agg) {
res.json(agg);
});
Fiddle here: http://jsfiddle.net/8n227L2o/
I've forked your Fiddle, and now I've used Underscore.js to group and filter your data according to your example table.
http://jsfiddle.net/pdc5rvyo/1/
It is quite basic, and uses nested tables. You should be able to customize it by allowing uses to change the order of the lists for example.
Code example:
var lhSortedList = _.groupBy(servers, function(item) {
return item._id.idc;
});
$scope.lh8Virtual = _.filter(lhSortedList['LH8'], function(item) {
return item._id.type === 'Virtual';
});
Here is an overview of how to do what you want dynamically:
var lhList = ['LH5', 'LH8']; // sourced from server ?
var lhSortedList = _.groupBy(servers, function(item) {
return item._id.idc;
});
$scope.lhData = {};
lhList.forEach(function(lhName) {
$scope.lhData[lhName + 'Virtual'] = _.filter(lhSortedList[lhName], function(item) {
return item._id.type === 'Virtual';
});
$scope.lhData[lhName + 'Physical'] = _.filter(lhSortedList[lhName], function(item) {
return item._id.type === 'Physical';
});
});

how to cut object from array and put it in object itself

I have response object which contain array:
Cars:
[0]: {
Name: 'Name1',
Color: 'Color2'
},
[1]: {
Name: 'Name2',
Color: 'Color2'
},
I want to copy the first item in the array and put it to object, Cars have to look:
Cars:
{
Name: 'Name1',
Color: 'Color'
},
If you're depicting things in memory, and Cars refers to an array containing objects, and your goal is to have Cars refer to just the first of those objects, you can do this:
Cars = Cars[0];
If the Cars variable was the only variable with a reference to the array, then the array becomes eligible for garbage collection. If the array's reference to the other object was the only reference to that object, then that other object ([1]) also becomes eligible for garbage collection.
Some ASCII-art might help here:
At first, you have this:
+-----------------+
+------+ +---------+ +--->| (object) |
| Cars |----->| (array) | | +-----------------+
+------+ +---------+ | | Name: 'Name1' |
| 0 |---+ | Color: 'Color2' |
| 1 |---+ +-----------------+
+---------+ |
| +-----------------+
+--->| (object) |
+-----------------+
| Name: 'Name2' |
| Color: 'Color2' |
+-----------------+
Then when you do:
Cars = Cars[0];
you have this:
+------+
| Cars |--------------------+
+------+ |
| +-----------------+
+---------+ +--->| (object) |
| (array) | | +-----------------+
+---------+ | | Name: 'Name1' |
| 0 |---+ | Color: 'Color2' |
| 1 |---+ +-----------------+
+---------+ |
| +-----------------+
+--->| (object) |
+-----------------+
| Name: 'Name2' |
| Color: 'Color2' |
+-----------------+
Note that nothing is pointing to the array anymore, so if garbage collection occurs, you end up with this:
+------+ +-----------------+
| Cars |----->| (object) |
+------+ +-----------------+
| Name: 'Name1' |
| Color: 'Color2' |
+-----------------+
Of course, if something else does have a reference to the array, the array wouldn't be GC'd (and similarly, if something else has a reference to the second object, it won't be GC'd). But that's what happens if we assume nothing else has those references.
check this: http://jsfiddle.net/romanian/6no49uwt/
response = [{
'Name': 'Name1',
'Color': 'Color2'
}, {
'Name': 'Name2',
'Color': 'Color2'
}]
console.log(response);
firstCar = response[0];
console.log(firstCar);
for display of console.log(), you will need firebug or some dev tool

Categories