Conditional selecting from a JSON array - arrays

I'm trying to select and display specific JSON data within an array. The data looks like this:
{ "thingys" : [
{
"type" : "thingy1",
"text" : "this is thingy1"
},
{
"type" : "thingy2",
"text" : "this is thingy2"
},
{
"type" : "thingy3",
"text" : "this is thingy3"
}
]}
I'm using json2html, and I would normally use something like
{"tag":"div","html":"${thingys.text}"}
This would be fine, but I want to be able to specify that I want ${thingys.text} where ${thingys.type} == "thingy3". How would I go about doing this?

best way to achieve something like this would be to include an inline function to process the the "thingys" Something like this
var transforms = {
'main': {"tag":"div","children":function() {
var out = [];
for(var i=0; i < this.thingys.length; i++)
if(this.thingys[i].test == "thingy3") out.push(this.things[i]);
return( json2html.transform(out,transforms.thing) );
}},
'thing':{"tag":"div","html":"${text}"}
};

Related

How do you access all values in JSON array?

The only data I can access right now is the beginning part of the array:
[
{
/*start*/
"username" : "Bob",
"password":"123456",
"bio":"Hi",
/*End*/
"data":
[
{
"pet" : "dog",
"age" : "20",
"city" : "5"
},
{
"pet" : "cat",
"age" : "18",
"city" : "7"
}
]
}
]
I can also access part of the data array, but I am trying to access all of it. For example: {item.data[1].pet}. I tried using a for loop but was unsuccessful with that. I am also using react-native flat list and doing dataSource: responseJSON.data didn't work for me either. I'm sure there has to be a way to access all of the values of petinstead of just one each time, I just don't know how to.
Also since I am a beginner any tips will be gladly appreciated.
EDIT: Attempts at trying to loop from outside the JSX:
var itemList = [];
for (var i = 0; i < responseJSON[0].data.length; i++) { itemList.push(<Text> {responseJson[0].data[i].pet}</Text>); }
I put that out of the render() Then I take itemList and stick it here:
<FlatList
data={ this.state.dataSource}
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) => <View>
{itemList}
</View>
}
keyExtractor={(item, index) => index}
/>
Now it's not understanding that itemList is a variable. I'm getting a syntax error.
EDIT 2: Thanks to everyone the only thing I need help with is putting a variable inside of componentDidMountin React Native.
I have no experience with React but from what I've found it seems it should be done this way:
const responseJson = [
{
/*start*/
"username" : "Bob",
"password":"123456",
"bio":"Hi",
/*End*/
"data":
[
{
"pet" : "dog",
"age" : "20",
"city" : "5"
},
{
"pet" : "cat",
"age" : "18",
"city" : "7"
}
]
}
];
const listItems = responseJson[0].data.map((details) =>
<li>{details.pet}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
The output I get is:
dog
cat
You can do it like this in javascript:
var json = {"data":[{"pet":"dog","age":"20","city":"5"},{"pet":"cat","age":"18","city":"7"}]};
for (var i = 0; i < json.data.length; i++) {
var object = json.data[i];
console.log(object);
console.log(object.pet, object.age, object.city);
}
Try this loop :
for (var i = 0; i < responseJSON[0].data.length; i++) {
alert(responseJSON[0].data[i].pet);
}
Working example here :
https://plnkr.co/edit/c1sZYKrBWHFJOKwHEMbU?p=preview
Why don't you convert all the data in the responseJson to objects using Lodash Library and then take the data object from it and assign it to a variable and then convert it back to an array. And after that you change the data source to that array you get
See the Documentation of Lodash here

Write an object to an .json file using angular?

I have an object like:
[
{
"text" : "Address of Bowlers game center in Chennai?",
"entities" : [
{
"entity" : "action",
"value" : "business"
},
{
"entity" : "intent",
"value" : "fetchItems"
},
{
"entity" : "bizCategory",
"value" : "bowling",
"start" : 11,
"end" : 30
},
{
"entity" : "wit$location",
"value" : "Chennai",
"start" : 34,
"end" : 40
}
]
},
{
.....more objects
}
]
Now I have to do some manipulation on this object and save the manipulated object into an .json file using angular js.
var originalObject = $http.get("data/chennai.json");
var manipuatedObject; // this is the manipulated object i get after applying some changes on originatalObject.
Now how can I save this manipuatedObject into an json file.
Try this:
function saveText(text, filename){
var a = document.createElement('a');
a.setAttribute('href', 'data:text/plain;charset=utf-u,'+encodeURIComponent(text));
a.setAttribute('download', filename);
a.click()
}
So a possible use might be:
var obj = {a: "Hello", b: "World");
saveText( JSON.stringify(obj), "filename.json" );

Get index of array item if item of array equals name

I have an array of items like this:
{
"dateAdded" : "2016-02-09 12:41:37",
"customValue" : "5",
"name" : "highestHeight"
},
{
"dateAdded" : "2016-02-09 12:41:37",
"customValue" : "46.91",
"name" : "highestWeight"
},
{
"dateAdded" : "2016-02-09 12:41:37",
"customValue" : "14972.02",
"name" : "highestScore"
},
I would like to get the items associated with the item that has the name = highestScore but not sure how or even what I should be searching for to find an example.
How about starting with the documentation on Array, which will show that it implements the CollectionType protocol, which has a filter function:
myArray.filter({ $0.name == "highestScore" })
That assumes it is an array of objects/types, and not an array of Dictionary instances. If that was the case, then you would use:
myArray.filter({ $0["name"] == "highestScore" })
You can look at functional filtering here: http://www.raywenderlich.com/82599/swift-functional-programming-tutorial
Do something like:
highscoreArray= yourArray.filter { (dictionary) in dictionary["name"]! == "highestScore" }
Haven't tested it but it should be along of the lines of that.

Grouping Of Data in AngularJs

I am building a site for a restaurant . On the site I am rendering the restaurant menu on a page .
The Menu Items Json, I am getting from server looks like this : -
{
"_id" : ObjectId("54c3c6e6cd7fe7df22cae87e"),
"restaurant" : ObjectId("54b3a7ef613e89f64654f2b3"),
"name" : "Pasta",
"itemCode" : "PST",
"price" : 240,
"sellingPrice" : 280,
"cuisine" : "Ittalian",
"category" : "starter",
"type" : "non-veg",
"created" : ISODate("2015-01-24T16:23:02.652Z"),
"Head" : pasta
"__v" : 0
}
So basically the requirement is to group menu items on basis of head field (which can be soups, pizza, pastas,etc).
so that all the item with "head" : "soups" will list down together and all item with "head" : "pizza" will list down together .
The way I thought of doing this is through designing custom filter, where I will pass all the unique "head" attribute and I will get data accordingly .
Just need a better and more optimize approach for the situation .
Depending on how often that filter will be called, you should probably just postprocess the data and create a new result set, grouped by the correct value. Something like (untested):
var jsonResults = [{head:'pasta',...},{head:'soups',...}];
, jsonResultsProcessed = { };
, rec
for(var i=0; i<jsonResults.length; i++) {
rec = jsonResults[i];
if(!jsonResultsProcessed[rec.head]) {
jsonResultsProcessed[rec.head] = [ rec ];
} else {
jsonResultsProcessed[rec.head].push(rec);
}
}
$scope.results = jsonResultsProcessed;
and then in your view, you can just refer to results.pizza or whatever.
var dishesPerHead = {};
var heads = [];
angular.forEach(dishes, function(dish) {
var dishesForHead = dishesPerHead[head];
if (!dishesForHead) {
dishesForHead = [];
heads.push(dish.head);
dishesPerHead[dish.head] = dishesForHead;
}
dishesForHead.push(dish);
}
Now you have an array of distinct heads, and for each head, dishesPerHead contains the array of dishes having this head.

Mapreduce split input string into output array

I am dealing with documents like the following one:
> db.productData.find({"upc" : "XXX"}).pretty()
{
"_id" : ObjectId("538dfa3d44e19b2bcf590a77"),
"upc" : "XXX",
"productDescription" : "bla foo bar bla bla fooX barY",
"productSize" : "",
"ingredients" : "foo; bar; foo1; bar1.",
"notes" : "bla bla bla"
}
>
I would like to have a document containing, among the fields, a list/array of splitted ingredients (on the ;). I want to split the string of the original collection into an array of strings.
I would like to map only some of the input fields in the output collection.
I would like to use mapreduce on MongoDB.
I've tried many different ways moving stuff from the map function to the reduce function failing to find a proper solution.
From all the attempts I performed, now I know I need to check for null values etc, so the following one is my last attempt:
The map function:
var mapperProductData = function () {
var ingredientsSplitted = values.ingredientsString.split(';');
var objToEmit = {barcode : "", description : "", ingredients : []};
// checking for null (is this strictly necessary? why?)
if (
this.hasOwnProperty('ingredients')
&& this.hasOwnProperty('productDescription')
&& this.hasOwnProperty('upc')
) {
for (var i = 0; i < ingredientsSplitted.length; i++) {
// I want to emit a new document only when I have all the splitted strings inside the array
if (i == ingredientsSplitted.length - 1) {
objToEmit.barcode = this.upc;
objToEmit.description = this.productDescription;
objToEmit.ingredients = ingredientsSplitted;
emit(this.upc, objToEmit);
}
}
}
};
The reduce function:
var reducerNewMongoCollection = function(key, values) {
return values;
};
The map-reduce call:
db.productData.mapReduce(
mapperProductData,
reducerNewMongoCollection,
{
out : "newMongoCollection" ,
query: { "values" : {$exists: true} }
}
);
I am getting an empty collection in output (newMongoCollection is empty).
What am I doing wrong?
Let's start from the beginning. Your map function should look like this:
var mapperProductData = function () {
var ingredientsSplitted = this.ingredients.split(';');
var objToEmit = {
barcode : this.upc,
description : this.productDescription,
ingredients : ingredientsSplitted
};
emit(this.upc, objToEmit);
};
Your map-reduce call should be:
db.productData.mapReduce(
mapperProductData,
reducerNewMongoCollection,
{
out : "newMongoCollection",
query : {
upc : { $exists : true },
productDescription : { $exists : true },
ingredients : { $exists : true , $type : 4 }
}
}
);
The query part will filter the documents that do have relevant fields. Also the query parameter $type will match only documents where ingredients is an array. This way you don't need to do complicated checking inside your map function and the number of documents sent to map function will be lower.
The result for your test document document will look like this:
key : XXX,
value: {
"barcode" : "XXX",
"description" : "bla foo bar bla bla fooX barY",
"ingredients" : [
"foo",
" bar",
" foo1",
" bar1."
]
}

Resources