Hi In my Controller from Server I am getting a JSON String
$scope.unsorted=data;
And the data looks like
[
{
"configId": 116,
"configName": "LAND_LINE",
"configFieldses": [
{
"FieldId": 784,
"FieldName": "engine.form.1",
"values": [
{
"keyname": "formName",
"value": "Account Number",
"id": 3068
},
{
"keyname": "formValuePosition",
"value": "right",
"id": 3069
}
]
},
{
"FieldId": 783,
"FieldName": "engine.form.0",
"values": [
{
"keyname": "formName",
"value": "Amount",
"id": 3074
},
{
"keyname": "formValuePosition",
"value": "right",
"id": 3075
},
{
"keyname": "regexGazatteer",
"value": "Total Charges :",
"id": 3076
}
]
},
{
"FieldId": 785,
"FieldName": "engine.table2",
"values": [
{
"keyname": "regexTableHeaderStart",
"value": null,
"id": 3079
},
{
"keyname": "regexTableBodyEnd",
"value": null,
"id": 3080
},
{
"keyname": "tableName",
"value": "invoice",
"id": 3078
}
]
}
]
}
]
I want to sort the configFieldses array based on FieldId and also the values array in each configFieldses based on id. So the JSON should looks like
[
{
"configId": 116,
"configName": "LAND_LINE",
"configFieldses": [
{
"FieldId": 783,
"FieldName": "engine.form.0",
"values": [
{
"keyname": "formName",
"value": "Amount",
"id": 3074
},
{
"keyname": "formValuePosition",
"value": "right",
"id": 3075
},
{
"keyname": "regexGazatteer",
"value": "Total Charges :",
"id": 3076
}
]
},
{
"FieldId": 784,
"FieldName": "engine.form.1",
"values": [
{
"keyname": "formName",
"value": "Account Number",
"id": 3068
},
{
"keyname": "formValuePosition",
"value": "right",
"id": 3069
}
]
},
{
"FieldId": 785,
"FieldName": "engine.table2",
"values": [
{
"keyname": "tableName",
"value": "invoice",
"id": 3078
}
{
"keyname": "regexTableHeaderStart",
"value": null,
"id": 3079
},
{
"keyname": "regexTableBodyEnd",
"value": null,
"id": 3080
}
]
}
]
}
]
What I have tried is first sort the parent array and then the child arrays.
var sortedfieldses = orderByFilter($scope.unsorted.configFieldses, '+FieldId');
But then How to remoive the old array from unsorted config and add the new to unsorted. And also how to loop through each and then sort it?
What is the best way?
Step 1: copy the object, then apply a custom sort function.
var sortedfieldses = angular.copy( $scope.unsorted.configFieldses );
sortedfieldses.sort( function( a, b ){
return a.FieldId > b.FieldId;
});
Step 2: Iterate through the "fieldses" and sort their children:
angular.forEach( sortedfieldses, function( field, key ){
field.values.sort( function( a, b ){
return a.id > b.id;
});
});
Actually re-reading your question, it sounds as though you just want to sort the 'unsorted' object in-place, rather than copying to a 'sorted' variable. If that's the case, skip the object copying and just do:
$scope.unsorted.configFieldses.sort( function( a, b ){
return a.FieldId > b.FieldId;
});
angular.forEach( $scope.unsorted.configFieldses, function( field, key ){
field.values.sort( function( a, b ){
return a.id > b.id;
});
});
The sort method alters the original array, rather than simply returning the sorted copy.
If you only need to sort the array, you could do this
$scope.unsorted=data;
// sort the parent
$scope.unsorted[0].configFieldses.sort(function(config1, config2) {
return config1.FieldId - config2.FieldId;
});
// sort the child values
$scope.unsorted[0].configFieldses.forEach(function(configField){
console.log(configField.values);
configField.values.sort(function(value1, value2) {
return value1.id - value2.id;
});
});
But if you want to display the the data using ng-repeat and orderBy filters, you could do use a nested ng-repeat like so.
<div ng-controller="ControllerX">
<div ng-repeat="configField in unsorted[0].configFieldses | orderBy:'FieldId' ">
<h3>{{configField.FieldId}}, {{configField.FieldName}}</h3>
<ul>
<li ng-repeat="value in configField.values | orderBy:'id'">
{{value.id}}, {{value.keyname}}
</li>
</ul>
</div>
</div>
Related
I have been struggling with json stuff. I want to find running state's href. How can I do that with jq or another like bash-style?
Here is my curl output:
{
"relations": {
"total": 9,
"link": [
{
"href": "https://vro:8281/vco/api/workflows/6433f56f-13b7-46a7-a9ec-a3e38c7ff69d/",
"rel": "up"
},
{
"href": "https://vro:8281/vco/api/workflows/6433f56f-13b7-46a7-a9ec-a3e38c7ff69d/executions/",
"rel": "add"
},
{
"attributes": [
{
"value": "8f961082-cccc-412f-9244-16ba5b949dbe",
"name": "id"
},
{
"value": "2019-09-28T17:20:40.691-01:00",
"name": "startDate"
},
{
"value": "2019-09-28T17:20:43.949-01:00",
"name": "endDate"
},
{
"value": "completed",
"name": "state"
},
{
"value": "test",
"name": "name"
},
{
"name": "currentItemDisplayName"
}
],
"href": "https://vro:8281/vco/api/workflows/6433f56f-13b7-46a7-a9ec-a3e38c7ff69d/executions/8f961082-cccc-412f-9244-16ba5b949dbe/",
"rel": "down"
},
{
"attributes": [
{
"value": "b28832cb-2a97-4ec8-848f-35fec95eb867",
"name": "id"
},
{
"value": "2019-09-28T17:21:04.643-01:00",
"name": "startDate"
},
{
"value": "running",
"name": "state"
},
{
"value": "test",
"name": "name"
},
{
"name": "currentItemDisplayName"
}
],
"href": "https://vro:8281/vco/api/workflows/6433f56f-13b7-46a7-a9ec-a3e38c7ff69d/executions/b28832cb-2a97-4ec8-848f-35fec95eb867/",
"rel": "down"
}
}
If I talk with example I want to find href key is https://vro:8281/vco/api/workflows/6433f56f-13b7-46a7-a9ec-a3e38c7ff69d/executions/b28832cb-2a97-4ec8-848f-35fec95eb867/ by way of running key.
After the sample JSON has been fixed, the following jq query:
.relations.link[]
| select( has("attributes") )
| select( any(.attributes[]; .value=="running" and .name == "state") )
| .href
produces:
"https://vro:8281/vco/api/workflows/6433f56f-13b7-46a7-a9ec-a3e38c7ff69d/executions/b28832cb-2a97-4ec8-848f-35fec95eb867/"
In two lines (i.e., with one pipe)
.relations.link[]
| select(any(.attributes[]?; .value=="running" and .name == "state")).href
I have a dimensional array like this
{
"items": [
{
"id": "file",
"value": "File",
"childs": [
{
"value": "New",
"status": 1
},
{
"value": "New",
"status": 2
},
{
"value": "New",
"status": 1
}
]
},
{
"id": "file",
"value": "File",
"childs": [
{
"value": "New",
"status": 1
},
{
"value": "New",
"status": 2
},
{
"value": "New",
"status": 1
}
]
}
]
}
How to filter items and own childs by childs.status
You have to use filter method in order to filter your array of items based on specific test, in your case when status 3 has been found, Here is a working example:
var json = {
"items": [
{
"id": "file",
"value": "File",
"childs": [
{
"value": "New",
"status": 1
},
{
"value": "New",
"status": 2
},
{
"value": "New",
"status": 1
}
]
},
{
"id": "file",
"value": "File",
"childs": [
{
"value": "New",
"status": 1
},
{
"value": "New",
"status": 3
},
{
"value": "New",
"status": 1
}
]
}
]
};
var result = json.items.filter(function(item) {
item.childs = item.childs.filter( function (child) {
return child.status === 3;
});
return item.childs.length > 0;
});
console.log({items: result});
I've setup a repl in which i've drawn out the method to filter your json. You can find it here; feel free to play around with it.
#younel's answer mutates the original array, I've also updated my repl with his approach to show how the original json is mutated.
Essence
look through each item in items
if a child in item matches the filter criteria, then keep the item and the filtered children
I'm assigned a task to get data using underscore js.
This is my JSON :
$scope.myData= {
"buslist":
{
"code":"1",
"message":"Success",
"fromStationCode":"71",
"searchResult": [
{
"arrivalTime": "17:00:00",
"availableSeats": "42",
"boardingPointDetails": [
{
"code": "1631",
"name": "Koyambedu",
"time": "09:30:00"
},
{
"code": "961296",
"name": "Nerkundram",
"time": "09:45:00"
}
]
},
{
"arrivalTime": "18:00:00",
"availableSeats": "32",
"boardingPointDetails": [
{
"code": "2084",
"name": "Adyar",
"time": "09:30:00"
},
{
"code": "961296",
"name": "Madurai",
"time": "09:45:00"
}
]
}
]
}
}
From this I want only "name" field. By doing this :
$scope.bdata = _.pluck($scope.myTest.buslist.searchResult, 'boardingPointDetails');
I got all "boardingPointDetails". The result looks like:
[ [
{
"code": "2084",
"name": "Adyar",
"time": "09:30:00"
},
{
"code": "961296",
"name": "Madurai",
"time": "09:45:00"
}
],[
{
"code": "1631",
"name": "Koyambedu",
"time": "09:30:00"
},
{
"code": "961296",
"name": "Nerkundram",
"time": "09:45:00"
}
],[
{
...
}
]
...
]
Help me to retrieve only "name" from this.
If you just want array of names like ['Koyambedu', 'Madurai'] then below code would work.
$scope.bdata = _.pluck($scope.myTest.buslist.searchResult, 'boardingPointDetails');
// Flatten the data.
$scope.flatbdata = _.flatten($scope.bdata, true);
$scope.flatbdata = $scope.flatbdata.filter(function(d){
return d != undefined && d.hasOwnProperty('name')
})
// map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results
$scope.names = $scope.flatbdata.map(function(d){
return d.name;
});
Refer below links :
http://underscorejs.org/#flatten
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
If you just want the array of names, here it is:
$scope.bdata = _.pluck($scope.myTest.buslist.searchResult, 'boardingPointDetails');
var res= _.flatten($scope.bdata);
res=_.pluck(res,'name');
console.log(res);
var temp = _.pluck(_.flatten($scope.bdata),'name')
temp will have ["Koyambedu", "Nerkundram", "Adyar", "Madurai"]
Try this.
$scope = {}; // in real project you don't need this. it's just for snippet.
$scope.myData = {
"buslist": {
"code": "1",
"message": "Success",
"fromStationCode": "71",
"searchResult": [{
"arrivalTime": "17:00:00",
"availableSeats": "42",
"boardingPointDetails": [{
"code": "1631",
"name": "Koyambedu",
"time": "09:30:00"
}, {
"code": "961296",
"name": "Nerkundram",
"time": "09:45:00"
}]
}, {
"arrivalTime": "18:00:00",
"availableSeats": "32",
"boardingPointDetails": [{
"code": "2084",
"name": "Adyar",
"time": "09:30:00"
}, {
"code": "961296",
"name": "Madurai",
"time": "09:45:00"
}]
}]
}
};
$scope.names = _.chain($scope.myData.buslist.searchResult).pluck("boardingPointDetails").flatten(true).map(function(item) {
return item.name;
}).value();
console.log($scope.names);
<script src="http://underscorejs.ru/underscore-min.js"></script>
I have the following collection:
"items": [{
"id": 1,
"title": "Montrachet",
"imageUrl": "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
"imageUrls": [
"http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
"http://media.riepenau.com/wines/17973_b.jpg",
"http://lorempixel.com/400/400/food/3"
],
"properties": [
{"description" : "Kırmızı Şaraplar Desc"},
{"region" :"Bordeaux"},
{"age": "16"},
{"producer" :"Kayra"},
{"grapeType":"Espadeiro"}
],
"priceGlass": "1",
"priceBottle": "2",
"year": "1999"
},
{
"id": 2,
"title": "Montrachet2",
"imageUrl": "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
"imageUrls": [
"http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
"http://media.riepenau.com/wines/17973_b.jpg",
"http://lorempixel.com/400/400/food/3"
],
"properties": [
{"description" : "Kırmızı Şaraplar Desc"},
{"region" :"Bordeaux"},
{"age": "16"},
{"producer" :"Kayra"},
{"grapeType":"Chardonnay"}
],
"priceGlass": "1",
"priceBottle": "2",
"year": "1999",
}
]
I want to grab unique grapeTypes from that collection. The returning array shold be ["Chardonnay","Espadeiro"]
What is the best way to do it with lodash?
I think this combination of pluck, map and filter should do it:
var result = _.chain(obj.items).pluck('properties').map(function(obj) {
return _.filter(obj, function(prop) {
return prop.grapeType;
})[0].grapeType;
}).uniq().value();
console.log(result);
Check the demo run below.
// Code goes here
var obj = {
items: [{
"id": 1,
"title": "Montrachet",
"imageUrl": "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
"imageUrls": [
"http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
"http://media.riepenau.com/wines/17973_b.jpg",
"http://lorempixel.com/400/400/food/3"
],
"properties": [{
"description": "Kırmızı Şaraplar Desc"
}, {
"region": "Bordeaux"
}, {
"age": "16"
}, {
"producer": "Kayra"
}, {
"grapeType": "Espadeiro"
}
],
"priceGlass": "1",
"priceBottle": "2",
"year": "1999"
},
{
"id": 2,
"title": "Montrachet2",
"imageUrl": "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
"imageUrls": [
"http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
"http://media.riepenau.com/wines/17973_b.jpg",
"http://lorempixel.com/400/400/food/3"
],
"properties": [{
"description": "Kırmızı Şaraplar Desc"
}, {
"region": "Bordeaux"
}, {
"age": "16"
}, {
"producer": "Kayra"
}, {
"grapeType": "Chardonnay"
}
],
"priceGlass": "1",
"priceBottle": "2",
"year": "1999",
}
]
};
var result = _.chain(obj.items).pluck('properties').map(function(obj) {
return _.filter(obj, function(prop) {
return prop.grapeType;
})[0].grapeType;
}).uniq().value();
document.write(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.8.0/lodash.js"></script>
UPD. If grapeType can be missing from properties then the script should be
var result = _.chain(obj.items).pluck('properties').map(function(obj) {
return (_.filter(obj, function(prop) {
return prop.grapeType;
})[0] || {}).grapeType;
}).compact().uniq().value();
Here's one way to do it with lodash:
_(items)
.pluck('properties')
.map(function(item) {
return _.find(item, _.ary(_.partialRight(_.has, 'grapeType'), 1));
})
.pluck('grapeType')
.uniq()
.value();
First, you get the properties arrays using pluck(). Next, you use find() to get the first object in this array that has a grapeType property. This is done using has(), and partially-applying the argument to build the callback function.
Next, you use pluck() again to get the actual property values. Finally, uniq() ensures there are no duplicates.
I need to aggregate an array as follows
Two document examples:
{
"_index": "log",
"_type": "travels",
"_id": "tnQsGy4lS0K6uT3Hwzzo-g",
"_score": 1,
"_source": {
"state": "saopaulo",
"date": "2014-10-30T17",
"traveler": "patrick",
"registry": "123123",
"cities": {
"saopaulo": 1,
"riodejaneiro": 2,
"total": 2
},
"reasons": [
"Entrega de encomenda"
],
"from": [
"CompraRapida"
]
}
},
{
"_index": "log",
"_type": "travels",
"_id": "tnQsGy4lS0K6uT3Hwzzo-g",
"_score": 1,
"_source": {
"state": "saopaulo",
"date": "2014-10-31T17",
"traveler": "patrick",
"registry": "123123",
"cities": {
"saopaulo": 1,
"curitiba": 1,
"total": 2
},
"reasons": [
"Entrega de encomenda"
],
"from": [
"CompraRapida"
]
}
},
I want to aggregate the cities array, to find out all the cities the traveler has gone to. I want something like this:
{
"traveler":{
"name":"patrick"
},
"cities":{
"saopaulo":2,
"riodejaneiro":2,
"curitiba":1,
"total":3
}
}
Where the total is the length of the cities array minus 1. I tried the terms aggregation and the sum, but couldn't output the desired output.
Changes in the document structure can be made, so if anything like that would help me, I'd be pleased to know.
in the document posted above "cities" is not a json array , it is a json object.
If changing the document structure is a possibility I would change cities in the document to be an array of object
example document:
cities : [
{
"name" :"saopaulo"
"visit_count" :"2",
},
{
"name" :"riodejaneiro"
"visit_count" :"1",
}
]
You would then need to set cities to be of type nested in the index mapping
"mappings": {
"<type_name>": {
"properties": {
"cities": {
"type": "nested",
"properties": {
"city": {
"type": "string"
},
"count": {
"type": "integer"
},
"value": {
"type": "long"
}
}
},
"date": {
"type": "date",
"format": "dateOptionalTime"
},
"registry": {
"type": "string"
},
"state": {
"type": "string"
},
"traveler": {
"type": "string"
}
}
}
}
After which you could use nested aggregation to get the city count per user.
The query would look something on these lines :
{
"query": {
"match": {
"traveler": "patrick"
}
},
"aggregations": {
"city_travelled": {
"nested": {
"path": "cities"
},
"aggs": {
"citycount": {
"cardinality": {
"field": "cities.city"
}
}
}
}
}
}