How to check an empty JSONArray in swiftyJSON - swift2

I have a JSON that have a JSONArray as a value in one of the json inside it. here is the example of it.
[
{
"id": 1,
"symptoms" : [{\"key\":\"sample1\",\"value\":5},{\"key\":\"sample2\",\"value\":5}]
},
{
"id": 2,
"symptoms" : [{\"key\":\"sample3\",\"value\":1}]
},
{ "id": 3,
"symptoms" : []
},
{
"id": 4,
"symptoms": [{\"key\":\"sample4\",\"value\":1}]
}
]
So what I am doing is that I am parsing the inner JSON and place it in a String Array. But whenever I look up to symptoms it skips the empty JSONArray. So whenever i print the String Array it goes like this (with the given sample on top) ["sample1", "sample2", "sample3", "sample4"]. But i want to do is to append an "" to the String Array whenever the JSONArray is empty so it should be like this ["sample1", "sample2", "sample3", "", "sample4"]. Anyone can help me with this? Here is my code
var arrayHolder: [String] = []
var idHolder: [Int] = []
for item in swiftyJSON.arrayValue {
idHolder.append(item["id"].intValue)
//for the inner JSON
let innerJSON = JSON(data: item["symptoms"].dataUsingEncoding(NSUTF8StringEncoding)!)
for symptoms in innerJSON.arrayValue {
arrayHolder.append(symptoms["key"].stringValue)
}
}
print(idHolder) // [1,2,3,4]
print(arrayHolder) // ["sample1","sample2","sample3","sample4"]

Just check if innerJSON is empty:
for item in swiftyJSON.arrayValue {
idHolder.append(item["id"].intValue)
//for the inner JSON
let innerJSON = item["symptoms"].arrayValue // non need to create a new JSON object
if innerJSON.isEmpty {
arrayHolder.append("")
} else {
for symptoms in innerJSON {
arrayHolder.append(symptoms["key"].stringValue)
}
}
}

Related

protobuf map value is object or array of object

I have
message {
message leadsEntity{
optional string name = 1;
}
optional string description = 1;
map <string, leadsEntity> entity = 2;
}
Now I can have 2 types of responses-
// 1st case
{
description : "this is test",
entity : {
key1 : { name : "name1" },
key2 : { name : "name2" }
}
}
Or
// 2nd case
{
description : "this is test",
entity : {
key1 : { name : "name1" },
key2 : [ { name : "name2" } ] //the value in array now
}
}
Now the above given proto message works perfectly for 1st case.
But how to handle 2nd case? where the value is an object array?
I assume by the use of optional that you prefer proto2
Your existing proto is invalid.
Your response types are going to make your life difficult because the entity values are a union of types.
Perhaps something like this:
syntax = "proto2";
message X {
message LeadsEntity{
optional string name = 1;
}
message LeadsEntities {
repeated LeadsEntity leads_entity = 1;
}
message Value {
oneof These {
LeadsEntity leads_entity = 1;
LeadsEntities leads_entities = 2;
}
}
optional string description = 1;
map <string, Value> entity = 2;
}
I gave the root message the name X
I added LeadsEntities to hold the repeated LeadsEntity
I added Value to hold the oneof
from google.protobuf.json_format import MessageToJson
import x_pb2
x = x_pb2.X()
x.description = "this is a test"
x.entity["key1"].leads_entity.name = "name1"
le = x.entity["key2"].leads_entities.leads_entity.add()
le.name = "name2"
print(MessageToJson(x))
Yields:
{
"description": "this is a test",
"entity": {
"key1": {
"leadsEntity": {
"name": "name1"
}
},
"key2": {
"leadsEntities": {
"leadsEntity": [
{
"name": "name2"
}
]
}
}
}
}

elasticsearch sort by price with currency

I have data
{
"id": 1000,
"price": "99,01USA",
},
{
"id": 1001,
"price": "100USA",
},
{
"id": 1002,
"price": "780USA",
},
{
"id": 1003,
"price": "20USA",
},
How I sort order by price (ASC , DESC)
You can alter it a little to parse price to integer and then sort it
You can create a dynamic sort function that sorts objects by their value that you pass:
function dynamicSort(property) {
var sortOrder = 1;
if(property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a,b) {
/* next line works with strings and numbers,
* and you may want to customize it to your needs
*/
var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
}
}
So you can have an array of objects like this:
var People = [
{Name: "Name", Surname: "Surname"},
{Name:"AAA", Surname:"ZZZ"},
{Name: "Name", Surname: "AAA"}
];
...and it will work when you do:
People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));
Actually this already answers the question. Below part is written because many people contacted me, complaining that it doesn't work with multiple parameters.
Multiple Parameters
You can use the function below to generate sort functions with multiple sort parameters.
function dynamicSortMultiple() {
/*
* save the arguments object as it will be overwritten
* note that arguments object is an array-like object
* consisting of the names of the properties to sort by
*/
var props = arguments;
return function (obj1, obj2) {
var i = 0, result = 0, numberOfProperties = props.length;
/* try getting a different result from 0 (equal)
* as long as we have extra properties to compare
*/
while(result === 0 && i < numberOfProperties) {
result = dynamicSort(props[i])(obj1, obj2);
i++;
}
return result;
}
}
Which would enable you to do something like this:
People.sort(dynamicSortMultiple("Name", "-Surname"));
Subclassing Array
For the lucky among us who can use ES6, which allows extending the native objects:
class MyArray extends Array {
sortBy(...args) {
return this.sort(dynamicSortMultiple(...args));
}
}
That would enable this:
MyArray.from(People).sortBy("Name", "-Surname");

Run Elasticsearch processor on all the fields of a document

I am trying to trim and lowercase all the values of the document that is getting indexed into Elasticsearch
The processors available has the field key is mandatory. This means one can use a processor on only one field
Is there a way to run a processor on all the fields of a document?
There sure is. Use a script processor but beware of reserved keys like _type, _id etc:
PUT _ingest/pipeline/my_string_trimmer
{
"description": "Trims and lowercases all string values",
"processors": [
{
"script": {
"source": """
def forbidden_keys = [
'_type',
'_id',
'_version_type',
'_index',
'_version'
];
def corrected_source = [:];
for (pair in ctx.entrySet()) {
def key = pair.getKey();
if (forbidden_keys.contains(key)) {
continue;
}
def value = pair.getValue();
if (value instanceof String) {
corrected_source[key] = value.trim().toLowerCase();
} else {
corrected_source[key] = value;
}
}
// overwrite the original
ctx.putAll(corrected_source);
"""
}
}
]
}
Test with a sample doc:
POST my-index/_doc?pipeline=my_string_trimmer
{
"abc": " DEF ",
"def": 123,
"xyz": false
}

Azure CosmoDB - MongoDb - C# - how to increment a value inside an array of Object?

I've this schema for my db:
{
"_id" : "test_schema",
"t" : 5,
"p" : [
{
"id" : "207",
"v" : 4
},
{
"id" : "309",
"v" : 1
}
....
]
}
I'm trying to $inc the v value of p.id equal to "207".
I'm currently able to inc the t value with this code:
var result = collection.UpdateOneAsync(new BsonDocument("_id", "test_schema"}), new BsonDocument("$inc", new BsonDocument("t", 4)), new UpdateOptions() { IsUpsert = true }).Result;
but whe i try to update a value on array nothing happen(even no error!):
var result = collection.UpdateOneAsync(new BsonDocument(new Dictionary<string, object>() { { "_id", "test_schema" }, { "p.id", "207" } }), new BsonDocument("$inc", new BsonDocument("p.v", 4)), new UpdateOptions() { IsUpsert = true }).Result;
Following MongoDB documentation i noticed that "p.v", 4 should be "p.$.v" but in cosmodb raise a not valid $ symbol exception.
Any suggestion?
Cosmos DB doesn't yet support positional operator, it is on the roadmap. The feedback item https://feedback.azure.com/forums/599059-azure-cosmos-db-mongodb-api/suggestions/20091454-positional-array-update-via-query-support is filed to track interest in this feature. Please vote there if you need this support.

Removing an elements from basicdblist

Hi i have collection which contains around 200 documents looks like
e.g
"_id": 0,
"name": "Demarcus Audette",
"scores": [
{
"type": "exam",
"score": 30.61740640636871
},
{
"type": "quiz",
"score": 14.23233821353732
},
{
"type": "homework",
"score": 31.41421298576332
},
{
"type": "homework",
"score": 30.09304792394713
}
]
now i wrote code like
DBCursor cursor = collection.find().sort(new BasicDBObject("scores.score":1));
while( cursor.hasNext() )
{
DBobject obj=cursor.next();
BasicDBList list=(BasicDBList) Bobj.get("scores");
// Now here i am getting list of documents which consists of an scores array and i need to remove 3rd elements of it and save collection.... but how to do?
if i use for loop like
for(int i=0;i<list.size();i++)
{
list.remove(2);------ it gives an error here
collection.save(obj);
}
}
Are you sure that you can sort it as 'scores.score'. As 'scores' is a list of objects you cant reference objects inside list using dot notation. Error should be on that line.
Edit:
DBCursor cursor = collection.find();
while ( cursor.hasNext()) {
DBObject dbObject = cursor.next();
BasicDBList dbList = (BasicDBList) (dbObject.get("score"));
//then use java Collections.sort() to sort the List (refer to two methods at the bottom)
dbList.remove(3);
collection.save(dbObject);
}
Use one of the following to sort the DBList
1 . Using Lambda expression
Collections.sort(dbList, (o1, o2) -> Double.compare(((BasicDBObject) o1).getDouble("score"), ((BasicDBObject) o2).getDouble("score")));
or java 7 <
Collections.sort(dbList, new Comparator<Object>() {
public int compare(Object o, Object o2) {
if (((BasicDBObject) o).getDouble("score") >= ((BasicDBObject) o2).getDouble("score")) {
return 1;
}
return -1;
}
});
See this link https://gist.github.com/machadolucas/5188447/raw/e3f5c44c2be756c6087809df63f7ea8f4682ace9/Mongo3_1.java
I`m has been
[some symbol for post this message)))]

Resources