I have the following part of a JSON file. I need to convert to a Javascript array using pure Javascript. Specifically, I need to have an array
userid, movieid, rating, timestamp only for rating greater than 4.0.
[{
"rating": 3.0,
"ratingsPK": {
"movieId": 2017,
"userId": 610
},
"timestamp": 913815387
}, {
"rating": 5.0,
"ratingsPK": {
"movieId": 2017,
"userId": 654
},
"timestamp": 959098930
}, {
"rating": 4.0,
"ratingsPK": {
"movieId": 2017,
"userId": 856
},
"timestamp": 1059863336
}, {
"rating": 2.0,
"ratingsPK": {
"movieId": 2017,
"userId": 903
},
"timestamp": 903628492
}, {
"rating": 3.5,
"ratingsPK": {
"movieId": 2017,
"userId": 1185
},
"timestamp": 1100560205
}]
You can use JSON.parse() to convert a JSON string to a JavaScript object. Then use Array#filter with appropriate predicate to get exactly what you need (in your case, timestamp greater than 4).
Simple "one-line" solution using JSON.parse() and Array.prototype.filter() functions:
var json_data = '[{"rating":3.0,"ratingsPK":{"movieId":2017,"userId":610},"timestamp":913815387},{"rating":5.0,"ratingsPK":{"movieId":2017,"userId":654},"timestamp":959098930},{"rating":4.0,"ratingsPK":{"movieId":2017,"userId":856},"timestamp":1059863336},{"rating":2.0,"ratingsPK":{"movieId":2017,"userId":903},"timestamp":903628492},{"rating":3.5,"ratingsPK":{"movieId":2017,"userId":1185},"timestamp":1100560205}]';
var arr = JSON.parse(json_data).filter(function(o){ return o.rating >= 4; });
console.log(arr);
The same but in EcmaScript6 manner(using arrow function):
var json_data = '[{"rating":3.0,"ratingsPK":{"movieId":2017,"userId":610},"timestamp":913815387},{"rating":5.0,"ratingsPK":{"movieId":2017,"userId":654},"timestamp":959098930},{"rating":4.0,"ratingsPK":{"movieId":2017,"userId":856},"timestamp":1059863336},{"rating":2.0,"ratingsPK":{"movieId":2017,"userId":903},"timestamp":903628492},{"rating":3.5,"ratingsPK":{"movieId":2017,"userId":1185},"timestamp":1100560205}]';
var arr = JSON.parse(json_data).filter((o) => o.rating >= 4 );
console.log(arr);
After converting to an object and filtering for rating, you could get an array with taking only the parts of the object, you need.
var data = '[{"rating":3.0,"ratingsPK":{"movieId":2017,"userId":610},"timestamp":913815387},{"rating":5.0,"ratingsPK":{"movieId":2017,"userId":654},"timestamp":959098930},{"rating":4.0,"ratingsPK":{"movieId":2017,"userId":856},"timestamp":1059863336},{"rating":2.0,"ratingsPK":{"movieId":2017,"userId":903},"timestamp":903628492},{"rating":3.5,"ratingsPK":{"movieId":2017,"userId":1185},"timestamp":1100560205}]',
result = JSON.parse(data).filter(function (a) {
return a.rating > 4;
}).map(function (a) {
return [a.ratingsPK.userId, a.ratingsPK.movieId, a.rating, a.timestamp];
});
console.log(result);
You can read the JSON File using XMLHttpRequest and that will return as string and imagine you got the file data in variable. jsonFile
Use JSON.parse like below.
var rating = JSON.parse(jsonFile);
Below is the Working Example.
var rating = [
{"rating":3.0,"ratingsPK":{"movieId":2017,"userId":610},"timestamp":913815387},
{"rating":5.0,"ratingsPK":{"movieId":2017,"userId":654},"timestamp":959098930},
{"rating":4.0,"ratingsPK":{"movieId":2017,"userId":856},"timestamp":1059863336},
{"rating":2.0,"ratingsPK":{"movieId":2017,"userId":903},"timestamp":903628492},
{"rating":3.5,"ratingsPK":{"movieId":2017,"userId":1185},"timestamp":1100560205}
];
var bestRated = [];
rating.forEach(function (item) {
if(item.rating > 4) {
bestRated.push({
userid: item.ratingsPK.userId,
movieid: item.ratingsPK.movieId,
rating: item.rating,
timestamp: item.timestamp
});
}
});
console.log('bestRated: ', bestRated);
JSON.parse() can be used to convert JSON to JS object. Below is a exmaple to suit your need.
var data='[{"rating":1.0,"ratingsABC":{"movieId":2017,"userId":123},"timestamp":913815387},{"rating":1.0,"ratingsABC":{"movieId":2017,"userId":123},"timestamp":913815387},{"rating":1.0,"ratingsABC":{"movieId":2017,"userId":123},"timestamp":913815387}]';
var sortedData= JSON.parse(data).filter((a) => a.rating >= 4 );
This is without using any fancy API:
var jsonArr = [
{"rating":3.0,"ratingsPK":{"movieId":2017,"userId":610},"timestamp":913815387},
{"rating":5.0,"ratingsPK":{"movieId":2017,"userId":654},"timestamp":959098930},
{"rating":4.0,"ratingsPK":{"movieId":2017,"userId":856},"timestamp":1059863336},
{"rating":2.0,"ratingsPK":{"movieId":2017,"userId":903},"timestamp":903628492},
{"rating":3.5,"ratingsPK":{"movieId":2017,"userId":1185},"timestamp":1100560205}];
var arr = [];
for(var x in jsonArr){
if(jsonArr[x]['rating'] > 4.0 ){
arr.push(jsonArr[x]['ratingsPK']['userId']);
arr.push(jsonArr[x]['ratingsPK']['movieId']);
arr.push(jsonArr[x]['rating']);
arr.push(jsonArr[x]['timestamp']);
}
}
console.log(arr);
Related
I'm stuck on this type of situation where the values of the object is changed to a different value. Is there way to shift a value to a key or would simply deleting and adding be better? I tried to loop to see which of the keys overlap in value and using the if statement and conditions i tried adding or deleting using Array methods. However, since the inter data is an object i am sruggling to find the right methods or even the process. I also tried using a function to insert the data and pushing to a new empty array that is returned from the function.
If I have objects in an array like so:
const data = [
{
"date": "12/22",
"treatment": "nausea",
"count": 2
},
{
"date": "12/23",
"treatment": "cold",
"count": 3
},
{
"date": "12/22",
"treatment": "cold",
"count": 2
}
];
and wanting to change the data like so:
const newData = [
{
"date": "12/22",
"cold": 2
"nausea": 2,
},
{
"date": "12/23",
"cold": 3
}
];
try this code using loop and reduce and every time add to new array
const data = [
{
"date": "12/22",
"treatment": "nausea",
"count": 2
},
{
"date": "12/23",
"treatment": "cold",
"count": 3
},
{
"date": "12/22",
"treatment": "cold",
"count": 2
}
];
const newData = [];
const dataByDate = data.reduce((acc, curr) => {
if (!acc[curr.date]) {
acc[curr.date] = { date: curr.date };
}
acc[curr.date][curr.treatment] = curr.count;
return acc;
}, {});
for (let date in dataByDate) {
newData.push(dataByDate[date]);
}
console.log(newData);
We want to reduce the data by unique dates. This can be done with:
An object as a dictionary,
Set or Map, or
Some other custom implementation.
Prefer to use Array.reduce() when reducing an array. This is standardized and more expressive than a custom implementation.
Using a map-like structure as the accumulator allows reduction of the dates by uniqueness and the data itself, simultaneously.
Note: Properties of objects are converted to Strings (except for Symbols). So if you want to use different "keys" that are equal after conversion (e.g. 0 and "0"), you cannot use objects; use Map instead.
(All our dates are Strings already, so this warning does not apply here.)
When using an object we can use the nullish coalescing assignment ??=: This allows us to assign an initial "empty" entry ({ date: dataEntry.date }) when encountering a new unique date.
Further, that assignment evaluates to the dictionary's entry; the entry that was either already present or just assigned.
Then we only need to assign the treatment and its count as a key-value pair to the entry.
const data = [
{ "date": "12/22", "treatment": "nausea", "count": 2 },
{ "date": "12/23", "treatment": "cold", "count": 3 },
{ "date": "12/22", "treatment": "cold", "count": 2 }
];
const newData = reduceByDate(data);
console.log(newData);
function reduceByDate(data) {
const dataByDate = data.reduce((dict, dataEntry) => {
const dictEntry = dict[dataEntry.date] // Get existing or ...
??= { date: dataEntry.date }; // ... just initialized entry.
dictEntry[dataEntry.treatment] = dataEntry.count;
return dict;
}, {});
// Transform dictionary to array of reduced entries
return Object.values(dataByDate);
}
You can make use of reduce() and Object.assign().
First we use reduce to combine objects with the same date into one object and then use assign to merge the values:
const data = [{
"date": "12/22",
"treatment": "nausea",
"count": 2
},
{
"date": "12/23",
"treatment": "cold",
"count": 3
},
{
"date": "12/22",
"treatment": "cold",
"count": 2
}
];
const newData = data.reduce((acc, curr) => {
const dateIndex = acc.findIndex(item => item.date === curr.date);
if (dateIndex === -1) {
acc.push({
date: curr.date,
[curr.treatment]: curr.count
});
} else {
acc[dateIndex] = Object.assign({}, acc[dateIndex], {
[curr.treatment]: curr.count
});
}
return acc;
}, []);
console.log(newData)
The data in SQL contains a lengthy JSON string in a cell similar to this:
{
"Name": "Example",
"Results": [
{
"ResultId": 0,
"AnswerIds": "[1,2,33,4,5]"
},
{
"ResultId": 1,
"AnswerIds": "[2,3,4,55,6]"
}
]
}
I have a list of replacement AnswerIds: Replace all 2 with 7, all 3's with 8's
How can I go about making a script for this?
I'm able to isolate the AnswerIds using crossapply and JSON_Query, but not sure how to go about replacing several changes in one array.
const json = {
"Name": "Example",
"Results": [
{
"ResultId": 0,
"AnswerIds": "[1,2,33,4,5]"
},
{
"ResultId": 1,
"AnswerIds": "[2,3,4,55,6]"
}
]
}
json.Results.forEach((itm, index)=> {
const arr = JSON.parse(itm.AnswerIds);
const replacedArray = arr.map(num=>{
if(num === 2) return 7;
if(num === 3) return 8;
return num;
});
json.Results[index].AnswerIds = JSON.stringify(replacedArray);
})
console.log(json);
This is what I have done, Take the json.Results array and iterate it with a forEach loop.
You can then access the AnswerIds object of each result.
Since the AnswerIds value is a string, we first convert it to an array.
Then we loop throught that array using a map, and do the replacements.
You might want to read up on JS maps, and JS foreach, JSON.parse, JSON.stringify
SQL Server 2016 has JSON support but you did not specify your SQL version.
Using DelimitedSplit8k you can do this:
-- SAMPLE STRING
DECLARE #string VARCHAR(1000) =
'{
"Name": "Example",
"Results": [
{
"ResultId": 0,
"AnswerIds": "[1,2,33,4,5]"
},
{
"ResultId": 1,
"AnswerIds": "[2,3,4,55,6]"
}
]
}';
-- SOLUTION
SELECT NewJSON =
(
SELECT
IIF(i.pos = 0,IIF(i.pos>0 AND sub.string IN(2,3), x.x, sub.string),
IIF(s2.ItemNumber=1,'"[','')+IIF(i.pos>0 AND sub.string IN(2,3),x.x,sub.string)) +
IIF(s2.ItemNumber>LEAD(s2.ItemNumber,1) OVER (ORDER BY s.ItemNumber,s2.ItemNumber),']"',
IIF(i.pos = 0,'',','))
FROM dbo.delimitedsplit8k(REPLACE(#string,CHAR(13),''),CHAR(10)) AS s
CROSS APPLY (VALUES(CHARINDEX('"AnswerIds": "',s.item))) AS i(pos)
CROSS APPLY (VALUES(SUBSTRING(s.item, i.pos+14, 8000))) AS ss(item)
CROSS APPLY dbo.delimitedsplit8k(ss.item,IIF(i.pos=0,CHAR(0),',')) AS s2
CROSS APPLY (VALUES(IIF(i.pos=0,s.item,
REPLACE(REPLACE(s2.item,']"',''),'[','')))) AS sub(string)
CROSS APPLY (VALUES(REPLACE(REPLACE(sub.string,'2',7),'3',8))) AS x(x)
ORDER BY s.ItemNumber, s2.ItemNumber
FOR XML PATH('')
);
Returns:
{
"Name": "Example",
"Results": [
{
"ResultId": 0,
"AnswerIds": "[1,7,33,4,5]"
},
{
"ResultId": 1,
"AnswerIds": "[7,8,4,55,6]"
}
]
}
I am trying to get a structure like
var tableData= [
['Hfbj'],
['Hygh'],
[6],
['mayur'],
[2563458952]
]
Here is my JSON data:
data:{
"address"': "Hfbj"
"id": 6
"landmark": "Hygh"
"name": "mayur"
"phone": 2563458952
"title": "aaa"
}
I am using react-native-table-component in which that type of structure needed. For that, I am doing the following but it showing data.map is not function and undefined.
let newdata = this.state.tableData[0].push(
[responseJson.data.title],
[responseJson.data.title]
);
this.setState({
tableData: newdata
});
How can I achieve it?
You could make use of Object.values and Array.map:
var reponseJson = {
data: {
"address": "Hfbj",
"id": 6,
"landmark": "Hygh",
"name": "mayur",
"phone": 2563458952,
"title": "aaa"
}
};
var newData = Object.values(reponseJson.data)
.map(item => [item]);
console.log(newData);
Note that I used the responseJson name to match your question, but as #Andreas pointed out, this is an object, not JSON.
If you need only certain columns (as requested in the comments below), use Object.keys and Array.filter on them before rebuilding the array:
var reponseJson = {
data: {
"address": "Hfbj",
"id": 6,
"landmark": "Hygh",
"name": "mayur",
"phone": 2563458952,
"title": "aaa"
}
};
var keysToKeep = ['address', 'landmark', 'title'];
var newData = Object.keys(reponseJson.data)
.filter(key => keysToKeep.includes(key))
.map(key => [reponseJson.data[key]]);
console.log(newData);
.map Is for arrays, whereas your responseJson.data is an Object. To get turn that Object into an array of its values you can do Object.values(responseJson.data)
I have json array data like this:
var arr= [
{
"id": 1,
"organizationName": "psda",
"Number": "12345"
},
{
"id": 2,
"organizationNameEN": "psda",
"Number": "123456"
}
]
AND after getting this data from json file i will use
var arr1=JSON.stringify(arr)
and then use
var arr2=JSON.parse(arr1)
var i=0;
while(i>=0){
var Data = $scope.documentData = {
"id":arr2[i]["id"],
"organizationNameGE":arr2[i]["organizationName"],
"Number":rawData[i]["Number"]
};
i++}
methods after that i try to get id arr2[i]["id"] and it seems to be undefined ,it throws exception like this Form failure:
Cannot read property 'id' of undefined
What should i change to make my code work?
Method 1
actually...you can't access the arr2[i].["id"] from while loop.
so create a global variable and then use it with this keyword
Method 2
if you are using angular framework.Try using with foreach loop.
var arr= [
{
"id": 1,
"organizationName": "psda",
"Number": "12345"
},
{
"id": 2,
"organizationNameEN": "psda",
"Number": "123456"
}
];
var arr1=JSON.stringify(arr);
var arr2=JSON.parse(arr1);
arr2.forEach(element =>{
alert(element.id);
});
I'm looking for the most effective way to replace a JSON Object in a file.
20150628 - Update at the bottom of this post
Here's the scenario:
I have a bunch of JSON files (many) and in these files are large chunks of JSON (sometimes 20-30K lines of it). These are configurations for various testing routines we have. Recently, a change was required to change an object from this:
"createdAt": {
"year": 2014,
"month": 11,
"dayOfMonth": 24,
"hourOfDay": 2,
"minute": 22,
"second": 54
}
to a format like this:
"createdAt":"2015-05-12T21:14:51Z"
Let's even make this easier. I want to replace all of the createdAt and updatedAt fields in my JSON object (which there can be many) with:
"createdAt":"2015-05-12T21:14:51Z"
or
"updatedAt":"2015-05-12T21:14:51Z"
There are NUMEROUS (100's of these) objects in each file, with different values for the fields. I need to go through and replace every createdAt and updatedAt object with the new format. The date's do not matter. I can have them be anything.
I can do this by hand, but it will literally take me a day or two to do of full time work (I know, I tried to do one file and after 1/2 hour I gave up, it was taking way too long).
How can I do this programmatically?
Regex? Sed? Something else?
Final note: I only need to do this once. After that, I won't need to do it again.
Thanks for any tips!
Example JSON: (Just imagine the real one is 30,000 lines!) :)
{ "products": [
{
"displayOrder": 3,
"product": {
"foo": "bar",
"createdAt": {
"year": 2014,
"month": 11,
"dayOfMonth": 24,
"hourOfDay": 2,
"minute": 22,
"second": 54
},
"description": "Fizz Bin",
"id": "8765309",
"modelNumber": "call-it",
"name": "Boom",
"price": {
"amount": 100,
"currency": "USD"
},
"type": "Active",
"updatedAt": {
"year": 2015,
"month": 1,
"dayOfMonth": 27,
"hourOfDay": 19,
"minute": 33,
"second": 25
}
}
},
{
"displayOrder": 4,
"product": {
"foo": "barx",
"createdAt": {
"year": 2013,
"month": 1,
"dayOfMonth": 4,
"hourOfDay": 3,
"minute": 2,
"second": 5
},
"description": "Fizzy Stuff",
"id": "876511111",
"modelNumber": "zoom-zoom-1000",
"name": "Zoom Zoom 1000",
"price": {
"amount": 1000,
"currency": "USD"
},
"type": "Active",
"updatedAt": {
"year": 2011,
"month": 5,
"dayOfMonth": 25,
"hourOfDay": 15,
"minute": 35,
"second": 55
}
}
}
]
}
UPDATE 20150628
For those wondering, here's the gulpfile I wrote to accomplish exactly what I wanted. It is based off of the accepted answer. It will recursively search the tree for what I'm looking for an replace it when found. Its not the prettiest thing in the world, but it did exactly what I needed and saved me a couple weeks of manual time. Total time to process all my files? Under 100ms. Amazing.
var gulp = require('gulp');
var change = require('gulp-change');
function searchTreeForDates(obj) {
if(typeof(obj) === 'object') {
for (var key in obj) {
if (typeof(obj[key]) === 'object' && (key === 'createdAt' || key === 'updatedAt')) {
obj[key] = "2015-06-29T00:53:00Z";
} else {
obj[key] = searchTreeForDates(obj[key])
}
}
}
return obj;
}
function updateDate(content) {
var obj = JSON.parse(content);
obj = searchTreeForDates(obj);
return JSON.stringify(obj);
}
gulp.task('change', function() {
return gulp.src('*.json')
.pipe(change(updateDate))
.pipe(gulp.dest('changed/'))
});
Here is an initial stab. You implement your own "date parsing logic." It requires you to install gulp. And save this in a gulpfile.js . You would need to possibly loop over all the properties that are "date" objects. But that logic isn't that hard.
var gulp = require('gulp');
var change = require('change');
function translateDate(dateField){
return dateField.A + dateField.b + ...;
}
function updateDate(content) {
var obj = JSON.parse(content);
//loop over the obj properties and call the below
// for the ones you want to change.
obj.dateField = translateDate(obj.dateField);
return JSON.stringify(obj);
}
gulp.task('change', function() {
return gulp.src('**/*.json')
.pipe(change(updateDate))
.pipe(gulp.dest('changed/'))
});
Why not manually?
function formatDate(dateObject){
var formattedDate =
dateObject['year']+'-'+
dateObject['month']+'-'+
dateObject['dayOfMonth']+'T'+
dateObject['hourOfDay']+':'+
dateObject['minute']+':'+
dateObject['second']+'Z';
}
var jsonArray = {...};
for(var key in jsonArray){
for(var i = 0; i < jsonArray[key].length; i++){
jsonArray[key][i]['createdAt'] = formatDate(jsonArray[key]['createdAt']);
jsonArray[key][i]['updatedAt'] = formatDate(jsonArray[key]['updatedAt']);
}
}
Open each file, change the property with a convert function and then save the new JSON:
function changeDate(obj) {
var newObject = obj.year + '-' + obj.month + '-' + obj.dayOfMonth + 'T' + obj.hourOfDay + ':' + obj.minute + ':' + obj.second;
return newObject;
}
// here you open the file and stores it's content in the products variable.
for (var i = 0; i < products.length; i++) {
var product = products[i];
product.product.createdAt = changeDate(product.product.createdAt);
product.product.updatedAt = changeDate(product.product.updatedAt);
}
// .. now you need to save the modified json