How can i group and restructure the json object using lodash.
Have a json object like this
var data = [
{
"Type": "W",
"Id": 1,
"Employee_Role_Desc": null,
"Employee_Role_Id": 1,
"StartDateTime": "2017-06-15T09:00:00",
"EndDateTime": "2017-06-15T12:30:00",
"Alert": null
},
{
"Type": "W",
"Id": 1,
"Employee_Role_Desc": null,
"Employee_Role_Id": 1,
"StartDateTime": "2017-06-15T09:00:00",
"EndDateTime": "2017-06-15T12:30:00",
"Alert": null
}, {
"Type": "W",
"Id": 1,
"Employee_Role_Desc": null,
"Employee_Role_Id": 3,
"StartDateTime": "2017-06-15T09:00:00",
"EndDateTime": "2017-06-15T12:30:00",
"Alert": null
}
]
Want to group t like this.
{
"Role_Id": 1,
"Date": "2017-06-15T05:12:22.9577063-05:00",
"**Blocks**": [
{
"StartDateTime": "2017-06-15T05:12:22.9586499-05:00",
"EndDateTime": "2017-06-15T05:12:22.9586499-05:00"
},
{
"StartDateTime": "2017-06-15T05:12:22.9586499-05:00",
"EndDateTime": "2017-06-15T05:12:22.9586499-05:00"
}
]
}
Group it by Employee_Role_Id and each StartDateTime and EndDateTime should be in a Blocks object
"Role_Id" in the result should be the "Employee_Role_Id" in resultant object.
You can achieve that using _.groupBy(), and _.map() in a chain:
const data = [{"Type":"W","Id":1,"Employee_Role_Desc":null,"Employee_Role_Id":1,"StartDateTime":"2017-06-15T09:00:00","EndDateTime":"2017-06-15T12:30:00","Alert":null},{"Type":"W","Id":1,"Employee_Role_Desc":null,"Employee_Role_Id":1,"StartDateTime":"2017-06-15T09:00:00","EndDateTime":"2017-06-15T12:30:00","Alert":null},{"Type":"W","Id":1,"Employee_Role_Desc":null,"Employee_Role_Id":3,"StartDateTime":"2017-06-15T09:00:00","EndDateTime":"2017-06-15T12:30:00","Alert":null}];
const result = _(data)
.groupBy('Employee_Role_Id') // group the items
.map((group, Role_Id) => ({ // map the groups to new objects
Role_Id,
Date: group[0].StartDateTime,
Blocks: group.map(({ StartDateTime, EndDateTime }) => ({ // extract the dates from the groups
StartDateTime,
EndDateTime
}))
}))
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Related
I have a table that looks like this:
id
json_col
35
[{"key_one":4,"key_two":{"value":1,"type":"static"}},{"key_one":27,"key_two":{"value":26,"type":"dynamic"}}]
36
[{"key_one":2,"key_two":{"value":33,"type":"static"}},{"key_one":9,"key_two":{"value":1,"type":"any"}}]
[
{
"id": 35,
"json_col": [
{
"key_one": 4,
"key_two": {
"value": 1,
"type": "static"
}
},
{
"key_one": 27,
"key_two": {
"value": 26,
"type": "dynamic"
}
}
],
"created_at": "2023-02-13T16:54:13.000000Z",
"updated_at": "2023-02-13T16:54:13.000000Z"
},
{
"id": 36,
"json_col": [
{
"key_one": 2,
"key_two": {
"value": 33,
"type": "static"
}
},
{
"key_one": 9,
"key_two": {
"value": 1,
"type": "any"
}
}
],
"created_at": "2023-02-13T16:54:56.000000Z",
"updated_at": "2023-02-13T16:54:56.000000Z"
}
]
How to get the row 35 that has key_two with value = 1 and type = static, using the query builder or a raw query?
you can use whereJsonContains with multi-dimentional array base on how you store them.
return Model::whereJsonContains('json_col', [ ['key_two' => [ 'value' => 1] ] ])
->whereJsonContains('json_col', [ ['key_two' => [ 'type' => 'static'] ] ])
->paginate(10); // or get()
just double check the sql output actually looks like your json format which should look something like
WHERE json_contains(`json_col`, '[{\"key_two\":{\"value\":1}}]')
AND json_contains(`json_col`, '[{\"key_two\":{\"type\":\"static\"}}]')
EDIT
If you need to search multiple match in single object, then this should do
return Model::whereJsonContains('json_col', [ ['key_two' => [ 'value' => 1, 'type' => 'static' ] ] ])
->paginate(10); // or get()
I am trying to write a SQL select statement for my AWS IoT rule to extract the values 'gateway_id and 'rssi' from the following MQTT message:
{
"end_device_ids": {
"device_id": "imd2",
"application_ids": {
"application_id": "pennal"
},
"dev_eui": "004E3A0DF76DC9E9",
"join_eui": "70B3D57ED003CBE8",
"dev_addr": "260BA9D0"
},
"correlation_ids": [
"as:up:01G30W0J4D65P6D50QH1DN3ZQP",
"gs:conn:01G2ZZ7FT9BH6J93WRYS4ATVDM",
"gs:up:host:01G2ZZ7FTN14103H90QN71Q557",
"gs:uplink:01G30W0HXWMES1Z7X7F2MCFMPF",
"ns:uplink:01G30W0HXXJM5PNGJAD0W01GGH",
"rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01G30W0HXWFR3HNGBZS7XJV15E",
"rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01G30W0J4D18JZW199EM8WERGR"
],
"received_at": "2022-05-14T08:47:25.837680984Z",
"uplink_message": {
"session_key_id": "AYBlRLSz9n83bW3WU3+GfQ==",
"f_port": 1,
"f_cnt": 5013,
"frm_payload": "DiAAAA==",
"decoded_payload": {
"rainmm": 0,
"voltage": 3.616
},
"rx_metadata": [
{
"gateway_ids": {
"gateway_id": "pennal-gw2",
"eui": "AC1F09FFFE057EC6"
},
"time": "2022-05-14T08:47:25.065794944Z",
"timestamp": 114306297,
"rssi": -126,
"channel_rssi": -126,
"snr": -8.25,
"uplink_token": "ChgKFgoKcGVubmFsLWd3MhIIrB8J//4FfsYQ+dnANhoMCJ3Z/ZMGEOPmv6sCIKjZvump7gYqCwid2f2TBhCA568f"
}
],
"settings": {
"data_rate": {
"lora": {
"bandwidth": 125000,
"spreading_factor": 11
}
},
"coding_rate": "4/5",
"frequency": "868100000",
"timestamp": 114306297,
"time": "2022-05-14T08:47:25.065794944Z"
},
"received_at": "2022-05-14T08:47:25.629041670Z",
"confirmed": true,
"consumed_airtime": "0.659456s",
"version_ids": {
"brand_id": "heltec",
"model_id": "cubecell-dev-board-class-a-otaa",
"hardware_version": "_unknown_hw_version_",
"firmware_version": "1.0",
"band_id": "EU_863_870"
},
"network_ids": {
"net_id": "000013",
"tenant_id": "ttn",
"cluster_id": "eu1",
"cluster_address": "eu1.cloud.thethings.network"
}
}
}
I have tried following the documentation here: AWS Documentation but am struggling with the nested part of the message.
my SQL statement at the moment is:
SELECT received_at as datetime, end_device_ids.device_id as device_id,
uplink_message.decoded_payload.rainmm as rainmm, uplink_message.decoded_payload.voltage as
voltage, uplink_message.settings.data_rate.lora.spreading_factor as sprfact,
uplink_message.consumed_airtime as time_on_air ,uplink_message.settings.timestamp as ts,
uplink_message.rx_metadata as rx,(select value gateway_ids from uplink_message.rx_metadata) as gw,
(select value rssi from uplink_message.rx_metadata)as rssi, get((select gateway_id from
uplink_message.rx_metadata),0).gateway_id as gwn FROM 'thethings/lorawan/matt-pennal-ire/uplink'
which returns
{
"datetime": "2022-05-15T12:19:11.947844474Z",
"device_id": "md4",
"rainmm": 5.842001296924288,
"voltage": 3.352,
"sprfact": 8,
"time_on_air": "0.092672s",
"ts": 3262497863,
"rx": [
{
"gateway_ids": {
"gateway_id": "pennal-gw2",
"eui": "AC1F09FFFE057EC6"
},
"time": "2022-05-15T12:19:11.178463935Z",
"timestamp": 3262497863,
"rssi": -125,
"channel_rssi": -125,
"snr": -7.5,
"uplink_token": "ChgKFgoKcGVubmFsLWd3MhIIrB8J//4FfsYQx4jXkwwaDAi/34OUBhCCy9XhAiDY6prg+ckHKgsIv9+DlAYQv8mMVQ=="
}
],
"gw": [
{
"gateway_id": "pennal-gw2",
"eui": "AC1F09FFFE057EC6"
}
],
"rssi": [
-125
]
}
but I would like it to return
{
"datetime": "2022-05-15T12:19:11.947844474Z",
"device_id": "md4",
"rainmm": 5.842001296924288,
"voltage": 3.352,
"sprfact": 8,
"time_on_air": "0.092672s",
"ts": 3262497863,
"gwn":"pennal_gw2"
"rssi":-126
}
Any help to get the values from the nested array would be greatly appreciated!
This question already has an answer here:
Asserting and using conditions for an array response in Karate
(1 answer)
Closed 2 years ago.
I want to loop through below nested json structure and want to update all the required fields, however I could achieve this through typescript but want to do this in karate JS, I do not see any examples how to nested for each works.
I want to update 26 periods data(here for readability i used 3), based on index I want to update period field, i.e. if(index == key), these 26 periods are under each car attribute.(NOTe: you again have multiple cars and multiple car attributes and each car attribute you have 26 periods data)
I cannot use this Karate - Match two dynamic responses only when you have single array list and have less data
[
{
"cars": [
{
"name": "car 1",
"periodsData": [
{
"period": "5ed73ed31a775d1ab0c9fb5c",
"index": 1
},
{
"period": "5ed73ed31a775d1ab0c9fb5d",
"index": 2
},
{
"period": "5ed73ed31a775d1ab0c9fb5e",
"index": 3
}
]
},
{
"name": "car 2",
"periodsData": [
{
"period": "5ed73ed31a775d1ab0c9fb5c",
"index": 1
},
{
"period": "5ed73ed31a775d1ab0c9fb5d",
"index": 2
},
{
"period": "5ed73ed31a775d1ab0c9fb5e",
"index": 3
}
]
},
{
"name": "car 3",
"periodsData": [
{
"period": "5ed73ed31a775d1ab0c9fb5c",
"index": 1
},
{
"period": "5ed73ed31a775d1ab0c9fb5d",
"index": 2
},
{
"period": "5ed73ed31a775d1ab0c9fb5e",
"index": 3
}
]
}
],
"totalPeriodEprps": [
{
"period": "5ed73ed31a775d1ab0c9fb5c",
"index": 1
},
{
"period": "5ed73ed31a775d1ab0c9fb5d",
"index": 2
},
{
"period": "5ed73ed31a775d1ab0c9fb5e",
"index": 3
}
]
}
carId ="dfd"
]
This above array repeats
Type script code
//periods is a map of index and values
async modifyCarsData(mid, id, periods, campaignData) {
//carData is a json file
carData.forEach(element => {
element.carId= id;
// Update all egrp periods
element.totalPeriodEGRPs.forEach(eGrpPeriod => {
// egrprd.period =
if (periods.size === element.totalPeriodEGRPs.length) {
periods.forEach((value, key) => {
if (key === eGrpPeriod.index.toString()) {
eGrpPeriod.period = value;
return true;
}
});
}
});
element.cars.forEach(carCell => {
// Logic for updating periods data
carCell .periodsData.forEach(periodAttribute => {
if (periods.size === carCell.periodsData.length) {
periods.forEach((value, key) => {
if (key === periodAttribute.index.toString()) {
periodAttribute.period = value;
return true;
}
});
}
});
});
});
Don't think of this as an update, but as a transform. I'm not using your example because it is un-necessarily complicated. Here is a simpler example that gives you all the concepts you need:
* def data = [{ name: 'one', periods: [{ index: 1, value: 'a' },{ index: 2, value: 'b' }]}, { name: 'two', periods: [{ index: 1, value: 'c' },{ index: 2, value: 'd' }]}]
* def fnPeriod = function(x){ x.value = x.value + x.index; return x }
* def fnData = function(x){ return { name: x.name, periods: karate.map(x.periods, fnPeriod) } }
* def converted = karate.map(data, fnData)
* print converted
Which prints:
[
{
"name": "one",
"periods": [
{
"index": 1,
"value": "a1"
},
{
"index": 2,
"value": "b2"
}
]
},
{
"name": "two",
"periods": [
{
"index": 1,
"value": "c1"
},
{
"index": 2,
"value": "d2"
}
]
}
]
If this doesn't work for you, please look for another tool. Karate is designed for testing and assertions, not doing what you normally do in programming languages. And I suspect that you have fallen into the trap of writing "over-smart tests", so please read this: https://stackoverflow.com/a/54126724/143475
Also refer: https://stackoverflow.com/a/53120851/143475
I have a basic store for inserting and deleting from an array
state: {
assessmentTypes : []
},
mutations: {
setAssessmentTypes(state, assessmentTypes) {
assessmentTypes.forEach(assessmentType => {
state.assessmentTypes.push(assessmentType);
});
},
removeAssessmentType ( state, assessmentTypeId ) {
let assessmentTypeIndex = state.assessmentTypes.map(assessmentType => assessmentType.id).indexOf(assessmentTypeId);
state.assessmentTypes.splice(assessmentTypeIndex, 1)
}
}
I get the state assessmentTypes in computed property in one of my components.
computed:{
assessmentTypes : {
get () {
return this.$store.state.assessmentTypes;
}
}
The problem is I am looping the array in dom for listing a div, but the computed property is not reactive. When I delete or insert a new object into/from the array (through actions), the dom is not rerendering.
Object structure
{
"id": "T7pLDdjmFWAqGiuqB",
"name": "bbb",
"code": "BBB",
"properties": {
combinationOfAssessments: false,
staffCanCreateInstance: false
},
"identifyingContext": {
"semId": "2",
"batchId": "54",
"staffId": "155",
"subjectId": "966",
"subbatchId": "391"
},
"permissions": {
"hod": "1",
"staff": "1"
},
"isActive": "1",
"createdBy": null,
"createdUserName": null,
"createdByUserType": null,
"createdDate": null,
"updatedDate": null,
"updatedBy": null,
"updatedUserName": null,
"updatedByUserType": null,
"propertiesValue": null
}
How can i get the value by id from a array in vue js? Many thanks with solution
list = [
{
"name": "Apple",
"id": 1,
},
{
"name": "Orange",
"id": 2,
}
]
watch: {
food: function (val) {
//Get food name by val(id)
}
}
Use Array.find method, which returns the value of the first element in the array that satisfies the provided testing function:
var food = list.find(food => food.id === val)
var name = food ? null : food.name
let list = [
{
"name": "Apple",
"id": 1,
},
{
"name": "Orange",
"id": 2,
}
]
console.log(
list.find(food => food.id === 1).name
)