I have an json array like this
var data= [
{
"id": 24,
"title": "BCOM",
"start": "2014-08-05 12:59:00 PM",
"end": "2014-08-05 2:59:00 PM",
"description": "mcom",
"DIFF": 120
},
{
"id": 26,
"title": "MCOM",
"start": "2014-08-10 12:59:00 PM",
"end": "2014-08-10 4:59:00 PM",
"description": "mcom",
"DIFF": 240
},
{
"id": 29,
"title": "MCOM",
"start": "2014-08-11 12:59:00 PM",
"end": "2014-08-11 8:59:00 PM",
"description": "mcom",
"DIFF": 480
},
{
"id": 30,
"title": "MCOM",
"start": "2014-08-13 12:59:00 PM",
"end": "2014-08-13 4:59:00 PM",
"description": "mcom",
"DIFF": 240
}
]
I want to make this array having index with out double quotes and change some index names , and some other modifications by using javascript array functions.
like
var data = [
{
id: 24,
title:"MCOM",
y: 120
},
{
id: 26,
title:"MCOM",
y: 240,
},
{
id: 29,
title:"MCOM",
y: 480,
},
]
Please help me in this, Thank you
Indexes with quotes ({ "title": "asdf" }) are equivalent to indexes without quotes ({ title: "asdf" }) in javascript, except that you can use more symbols like spaces, brackets or keywords in the quoted version.
Also, in JSON, you HAVE to add quotes around indexes, otherwise it's not valid JSON.
About the modifications, you can use Array.prototype.map() to do this
var newData = data.map(function (el) {
return {
id: el.id,
title: el.title,
y: el.DIFF
};
});
console.log(newData);
Use Array map function for this
var result = data.map(function (obj) {
return {id:obj.id,title:obj.title,y:obj.DIFF};
})
console.log(result);
I'm assuming in the result there should be BCOM as title for id, 24. I this is a type that there it's written as MCOM.
what I think "" shouldn't matter for keys.
Do some googling ;-) it will help..
var data = '{ "name": "John Smith" }'; //Let's say you got this
data = data.replace(/\"([^(\")"]+)\":/g,"$1:"); //This will remove all the quotes
data; //'{ name: "John Smith" }'
Hope it helps.
Related
I'll freely admit that Javascript is not my strongest language, and React Native is very new, so, there may be an obviously easy way to do this that I'm not seeing.
I've got an API that presents some transaction data in a simple structure:
[
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
},
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
},
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
]
I want to present this data using a SectionList component, with the transactions in sections by date. My (likely crude) attempt to solve this was going to be to transform this data into the following structure:
[
{
"date": "2021-09-10",
"transactions": [
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
}
]
},
{
"date": "2021-09-09",
"transactions": [
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
}
]
},
{
"date": "2021-09-07",
"transactions": [
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
]
}
]
But I'm honestly lost as to how to transform this data (or if there's a better way to solve this problem). I started by using Lodash's groupBy function, which seemed promising, but it looks like SectionList doesn't want an object, it wants an array.
Transforming the output of groupBy into an array straight off drops the keys and I've got grouped data but no clear value for the section header.
Again, there's probably some deviously simple way to address this, data comes in as a flat array all the time. I appreciate any guidance, assistance, or examples anybody can point me to.
const input = [
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
},
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
},
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
]
const result = input.reduce((accum, current)=> {
let dateGroup = accum.find(x => x.date === current.date);
if(!dateGroup) {
dateGroup = { date: current.date, transactions: [] }
accum.push(dateGroup);
}
dateGroup.transactions.push(current);
return accum;
}, []);
console.log(result)
Given an array, whenever your result is expecting to have same number of elements, use map, but since your result has different number of elements, use reduce as shown above. The idea is by having reduce, loop over each element, see if you can find the element, and push the current element into the list
The lodash groupBy just helps you with group data, you should process grouped data by converting it into your format.
const input = [
{
"id": 1,
"title": "Apple Store",
"date": "2021-09-10",
"amount": "$100.00",
},
{
"id": 41,
"title": "Zulauf, Walter and Metz",
"date": "2021-09-10",
"amount": "$14.00",
},
{
"id": 9,
"title": "Aufderhar PLC",
"date": "2021-09-09",
"amount": "$78.00",
},
{
"id": 10,
"title": "Bayer and Sons",
"date": "2021-09-07",
"amount": "$67.00",
}
];
const groupedArray = _.groupBy(input, "date");
let result = [];
for (const [key, value] of Object.entries(groupedArray)) {
result.push({
'date': key,
'transactions': value
})
}
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
simply
const data =
[ { id: 1, title: 'Apple Store', date: '2021-09-10', amount: '$100.00' }
, { id: 41, title: 'Zulauf, Walter and Metz', date: '2021-09-10', amount: '$14.00' }
, { id: 9, title: 'Aufderhar PLC', date: '2021-09-09', amount: '$78.00' }
, { id: 10, title: 'Bayer and Sons', date: '2021-09-07', amount: '$67.00' }
]
const res = Object.entries(data.reduce((r,{id,title,date,amount})=>
{
r[date] = r[date] ?? []
r[date].push({id,title,date,amount})
return r
},{})).map(([k,v])=>({date:k,transactions:v}))
console.log( res )
.as-console-wrapper { max-height: 100% !important; top: 0 }
With lodash you can group by the date then map to the required form:
const input = [{"id":1,"title":"Apple Store","date":"2021-09-10","amount":"$100.00"},{"id":41,"title":"Zulauf, Walter and Metz","date":"2021-09-10","amount":"$14.00"},{"id":9,"title":"Aufderhar PLC","date":"2021-09-09","amount":"$78.00"},{"id":10,"title":"Bayer and Sons","date":"2021-09-07","amount":"$67.00"}];
const result = _.map(
_.groupBy(input, 'date'),
(transactions, date) => ({ date, transactions })
)
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
you could use loadash
var result = _(data)
.groupBy(item => item.date)
.map((value, key) => ({date: key, transactions: value}))
.value();
This question already has answers here:
Get list of duplicate objects in an array of objects
(8 answers)
Closed 1 year ago.
I have this long list of array and I want to filter the object return by id. For example, I want to get objects with the same id, in this case object at index 0 and index 2. How can i achieve this? I have tried the for loop method but it's not going anywhere
var arr = [
{
"name": "David",
"last_updated": "2021-04-12 15:42:51",
"id": "175",
"class": "CLASS 2019",
"stops": [
{
"total": "29",
"graduated": "1900"
},
],
},
{
"name": "Cameron",
"last_updated": "2021-04-12 15:42:51",
"id": "180",
"class": "CLASS 2021",
"stops": [
{
"total": "40",
"graduated": "2500"
},
],
},
{
"name": "Rose",
"last_updated": "2021-04-12 15:42:51",
"id": "175",
"class": "CLASS 2008",
"stops": [
{
"total": "50",
"graduated": "1000"
},
],
},
This is a short snippet that I have in mind and tried. I'm aware that it doesn't make sense hence why I'm asking here. Any explanations and workarounds is very much appreciated
for(let i=0; i<arr.length; i++) {
if(arr[i].id === arr[i].id) {
console.log(arr[i])
}
}
Please correct me if I am misunderstanding here, but you simply want to filter the array of objects to only keep objects whose id value appears more than once in the array.
If that's the case, then my solution below should answer your question. Essentially, what it does is filter the source array by a map of all id values and filters to only objects whose id appears more than once. Using length - 1 works interchangeably with length > 1 here as subtracting 1 will product a falsy value 0 for those with only one instance of their id. The only difference here would be that this would not filter objects without an id property.
If you will be dealing with objects without an id property and would like to exclude those in the final result, change length - 1 to length > 1.
const arr = [
{ name: "David", last_updated: "2021-04-12 15:42:51", id: "175", class: "CLASS 2019", stops: [ { total: "29", graduated: "1900" } ] },
{ name: "Cameron", last_updated: "2021-04-12 15:42:51", id: "180", class: "CLASS 2021", stops: [ { total: "40", graduated: "2500" } ] },
{ name: "Rose", last_updated: "2021-04-12 15:42:51", id: "175", class: "CLASS 2008", stops: [ { total: "50", graduated: "1000" } ] }
];
const uniqObjs = [];
const dupeObjs = [];
arr.forEach(obj => [uniqObjs,dupeObjs][+(arr.map(obj => obj.id).filter(id => id === obj.id).length > 1)].push(obj));
console.log('uniqObjs:',uniqObjs);
console.log('dupeObjs:',dupeObjs);
You can use array.filter
var arr = [{
"name": "David",
"last_updated": "2021-04-12 15:42:51",
"id": "175",
"class": "CLASS 2019",
"stops": [{
"total": "29",
"graduated": "1900"
}, ],
},
{
"name": "Cameron",
"last_updated": "2021-04-12 15:42:51",
"id": "180",
"class": "CLASS 2021",
"stops": [{
"total": "40",
"graduated": "2500"
}, ],
},
{
"name": "Rose",
"last_updated": "2021-04-12 15:42:51",
"id": "175",
"class": "CLASS 2008",
"stops": [{
"total": "50",
"graduated": "1000"
}, ],
},
]
const id175 = arr.filter(item => item.id === '175');
console.log(id175)
I would like to convert objects in JavaScript, but I'm not really sure of the best way to do it. I don't often code in the language so I don't really know much of the fundamentals- this is the object I get back from an API call in a React project:
{
"api": {
"results": 380,
"fixtures": [
{
"fixture_id": 65,
"league_id": 2,
"league": {
"name": "Premier League",
"country": "England",
"logo": "https://media.api-sports.io/football/leagues/2.png",
"flag": "https://media.api-sports.io/flags/gb.svg"
},
"event_date": "2018-08-10T19:00:00+00:00",
"event_timestamp": 1533927600,
"firstHalfStart": 1533927600,
"secondHalfStart": 1533931200,
"round": "Regular Season - 1",
"status": "Match Finished",
"statusShort": "FT",
"elapsed": 90,
"venue": "Old Trafford (Manchester)",
"referee": null,
"homeTeam": {
"team_id": 33,
"team_name": "Manchester United",
"logo": "https://media.api-sports.io/football/teams/33.png"
},
"awayTeam": {
"team_id": 46,
"team_name": "Leicester",
"logo": "https://media.api-sports.io/football/teams/46.png"
},
"goalsHomeTeam": 2,
"goalsAwayTeam": 1,
"score": {
"halftime": "1-0",
"fulltime": "2-1",
"extratime": null,
"penalty": null
}
}
]
}
}
I would like to convert it to this array (the array holds multiple objects):
[
{
"homeTeam": {
"id": 33,
"name": "Manchester United",
"teamId": 33
},
"awayTeam": {
"id": 46,
"name": "Leicester",
"teamId": 46
},
"outcome": {
"goalsScoredByAwayTeam": 2,
"goalsScoredByHomeTeam": 1
},
"resulted": true,
"type": "LEAGUE"
}
]
The teamId and id actually need to lookup another object before the final output.
I'm not sure what the best way to do it is. This is my function so far, trying to make use of optional chaining:
function convertFixturesToArray() {
fixturesStore.getFixtures()?.api?.fixtures?.length ? fixtures.api.fixtures.map(fixture => (
//TRANSFORMATION GOES IN HERE
)) : null;
}
You seem on the right track. It should be something like this (written in a slightly more modern JS)
convertFixturesToArray = () => fixturesStore.getFixtures()?.api?.fixtures?.map?.(fixture => {
//Do whatever check you need here with the fixture object
return {
homeTeam: { ...fixture.homeTeam },
awayTeam: { ...fixture.awayTeam },
outcome: {
goalsScoredByAwayTeam: fixture.goalsAwayTeam,
goalsScoredByHomeTeam: fixture.goalsHomeTeam,
},
type: 'LEAGUE',
resulted: true,
},
}) ?? [];
It looks like you're trying to get certain key/value pairs from your api response. With a mix of map, reduce, and find, you can get the values you're looking for by defining them in an array (i.e. desiredProps).
Of course, adding the "outcome" field and your other hardcoded fields would require a bit more logic on top of this. Boris' answer addresses this problem. I've taken a more flexible approach.
let apiResult = {
"fixtures": [
{
"prop1": "a1",
"prop2": "a2",
"prop3": "a3"
},
{
"prop1": "b1",
"prop2": "b2",
"prop3": "b3"
}
]
}
let desiredProps = ["prop2", "prop3"]
let result = apiResult.fixtures.map(x => {
return Object.keys(x).reduce((acc, curr) => {
if (desiredProps.find(y => y === curr)) {
acc[curr] = x[curr]
}
return acc
}, {})
})
console.log(result)
I am trying to group this JSON by using BroadCategory attribute of category
[{
"brand": "Brand3",
"category": {
"popularity_index": 7,
"BroadCategory ": "BroadCategory4",
"MainCategory": "MainCategory410",
"GeneralCategory": "GeneralCategory41"
},
"description": "colonialism",
"discount": 17,
"id": 9
}, {
"brand": "Brand2",
"category": {
"popularity_index": 5,
"BroadCategory ": "BroadCategory2",
"MainCategory": "MainCategory210",
"GeneralCategory": "GeneralCategory21"
},
"description": "desc2",
"discount": 15,
"id": 2
}]
I went through underscore.js - _.groupBy nested attribute but this has array inside JSON for location
I tried something like:
var grpArray = _.groupBy(products, function (element) {
return element.category.BroadCategory;
})
but its not working. Why can't I access BroadCategory ?
You have to trim a space "BroadCategory "
"BroadCategory ": "BroadCategory2",
Change to:
"BroadCategory": "BroadCategory2",
OR:
_.groupBy(products, function (element) {
return element.category['BroadCategory '];
})
I have a JSON formed like you can see further below. I am having trouble looping through and defining the correct points to loop over, as I'm not that experienced with arrays in objects and complicated JSON.
What I'm mainly looking for is some pointers on the parse / toJSON parts of my collection, or other places I might be failing with this particular structure.
I am trying to loop over the values and output data from the event and the type name using backbone and dust. Normally I can just loop over my JSON by defining the collection in the view, e.g. calling this like so:
dust.render("dialog-decoderevents-items", { events : currentUser.eventList.toJSON() }, function(err, out) {
_this.$(".ab-tvg-prg-opt-future").append($(out));
});
That would normally allow me to just make a loop in dust and output data like this:
{#events}
{#tvProgram}{name}{/tvProgram}
{type}
{/events}
I have tried the dust examples using array and current context on this JSON and it will output something with no problem. I think the problem lies in what I define as the starting point of the model and collection.
I have both a parse function and a toJSON function in my collection now. But I also don't know what to define as an id on the model, since as you can see the id is defined inside the event, and not on the outside where I'd normally use it. Ideas? All the data is below.
JSON
{
"status": null,
"value": [
{
"event": {
"id": "RWtzdHJlbSBvcHBkcmFnZWxzZTxsZHR2cGQ+MTM2NDMwMDQwMDAwMDxsZHR2cGQ+MTM2NDMwNDAwMDAwMA==",
"name": "A glorious event",
"description": "Some long description about the event",
"startTime": {
"year": 2013,
"month": 3,
"date": 26,
"hour": 13,
"minute": 20,
"seconds": 0
},
"endTime": {
"year": 2013,
"month": 3,
"date": 26,
"hour": 14,
"minute": 20,
"seconds": 0
}
},
"type": "Party"
},
{
"event": {
"id": "Rmx5aW5nIFdpbGQgQWxhc2thPGxkdHZwZD4xMzY0MzA2NDAwMDAwPGxkdHZwZD4xMzY0MzEwMDAwMDAw",
"name": "A glorious event",
"description": "Some long description about the event",
"startTime": {
"year": 2013,
"month": 3,
"date": 26,
"hour": 15,
"minute": 0,
"seconds": 0
},
"endTime": {
"year": 2013,
"month": 3,
"date": 26,
"hour": 16,
"minute": 0,
"seconds": 0
}
},
"type": "Birthday"
},
{
"event": {
"id": "UG9pcm90PGxkdHZwZD4xMzY0MzE2NjAwMDAwPGxkdHZwZD4xMzY0MzE5NjAwMDAw",
"name": "A glorious event",
"description": "Some long description about the event",
"startTime": {
"year": 2013,
"month": 3,
"date": 26,
"hour": 17,
"minute": 50,
"seconds": 0
},
"endTime": {
"year": 2013,
"month": 3,
"date": 26,
"hour": 18,
"minute": 40,
"seconds": 0
}
},
"type": "Birthday"
},
{
"event": {
"id": "VGhlIEJpZyBCYW5nIFRoZW9yeTxsZHR2cGQ+MTM2NDMxOTAwMDAwMDxsZHR2cGQ+MTM2NDMyMDgwMDAwMA==",
"name": "A glorious event",
"description": "Some long description about the event",
"startTime": {
"year": 2013,
"month": 3,
"date": 26,
"hour": 18,
"minute": 30,
"seconds": 0
},
"endTime": {
"year": 2013,
"month": 3,
"date": 26,
"hour": 19,
"minute": 0,
"seconds": 0
}
},
"type": "Birthday"
}]}
Model
var mainEvent = Backbone.Model.extend({
idAttribute : "id",
defaults : {
type: null,
event : {
id : null,
name: null,
description: null,
channelId: null,
startTime: null,
endTime: null
}
}
});
Collection
var eventCollection = Backbone.Collection.extend({
model: mainEvent,
parse : function(json, options) {
var retr = [], tmp;
if (json.status === ajaxStatus.success) {
switch(options.action) {
default:
retr = json.value;
break;
}
if (options.action === "events") {
currentUser.eventList = new eventCollection(retr, { action : "events" });
}
}
else if (json.status === ajaxStatus.notAuthenticated) {
currentUser.trigger("notLoggedIn");
return [];
}
return retr;
},
toJSON : function(){
var ret = this.constructor.__super__.toJSON.call(this);
// _.each(ret, function (item) {
// console.log('l1'+item);
// ret.push(item);
// });
return ret;
}
});
Idea after quickly reading over your issue (take it with a grain of salt as I've never used dust or backbone before):
Couldn't you just create a controller that stores a content array for each event object? That way, all you would have to do when you were extracting the JSON file is add each event to the controller, and iterate over that in your HTML. You could then extract the id with id = event[id] or something.
EDIT: Here's an example with AJAX, I know you're not using that but the parsing bit should at least be helpful:
function getParties() {
$.ajax({
url: 'json/party.json',
dataType: 'json',
async: false,
success: function(data) {
console.log("Data:", data.value);
for (var i=0, occurence; occurence = data.value[i]; i++) {
var event = {};
event.type = occurence.type;
for (var key in occurence.event) {
event[key] = occurence.event[key];
}
console.log("Event:", event);
// Do something with event... Maybe add to content array.
}
}
});
}
The "event" should now be in simple javascript. If you want to access a known field within it, you can say event["id"] for example. To iterate through all values, use the following loop.
for (var key in event) {
console.log("Key: " + key + ", Value: " + event[key]);
}
You also should be able to get the value with {id}, for example, in Backbone. Something similar works in Ember when the created "event" objects are pushed to some controller's content array, which is what I'm using.