Vue.js Computed Property Filtering - javascript

I have a Vue.js computed property as follows.
odds() {
let race = this.data.events.runners.filter(item => item.course === this.course && item.time === this.time)
let runner = race[0].data.filter(item => item.name === this.runner)
return runner[0].odds
}
Although it returns the expected value I think it looks dirty. Can any one suggest best way to write this code.
Sample JSON is as follows.
{
"courses": [{
"type": "horses",
"course": "Exeter"
}],
"runners": [{
"course": "Exeter",
"time": "14:10",
"data": [{
"number": "1",
"name": "White Lilac",
"odds": "6\/1"
}, {
"number": "2",
"name": "Sauvignon",
"odds": "5\/1"
}, {
"number": "3",
"name": "Foxy Lass",
"odds": "33\/1"
}, {
"number": "4",
"name": "Hot Ryan",
"odds": "8\/1"
}, {
"number": "5",
"name": "Arqalina",
"odds": "11\/8"
}, {
"number": "6",
"name": "Presenting Lucina",
"odds": "14\/1"
}, {
"number": "7",
"name": "Persistantprincess",
"odds": "12\/1"
}, {
"number": "8",
"name": "Windy Bottom",
"odds": "20\/1"
}, {
"number": "9",
"name": "Shotgun Sally",
"odds": "33\/1"
}, {
"number": "10",
"name": "Rule The Ocean",
"odds": "9\/1"
}, {
"number": "11",
"name": "Avithos",
"odds": "12\/1"
}, {
"number": "12",
"name": "Monet Moor",
"odds": "16\/1"
}]
}]
}
I would like to know if there is a much better way to do this. Thanks in advance.

Your existing code is nice enough. but one change is your course and time make it unique fields so there will only be one index always so its better to exit early. (you can add false check for not found yourself).
var requiredCourse = (courseDetails)=>courseDetails.course === this.selectedCourse && courseDetails.time === this.selectedTime;
var requiredhorse = (horse)=> horse.name === this.runner;
var courseIndex = data.findIndex(requiredCourse);
var horseOdds = data[courseIndex].data.findIndex(requiredhorse);
console.log(data[courseIndex].data[horseOdds])
But if you have the ability to change the JSON structure. then just directly make the course and time as keys so you can directly access without need for filter or findIndex. hope this make is it little bit cleaner for your liking.

Related

How can I .filter an object by elements within an array inside an object?

I've been playing around trying to learn in an API project using Postman and conducting tests using JavaScript. So far, I have succeeded with the help of reading on websites and watching YouTube videos. Of course, previous tests and playing around have been fairly easy but now I came to a stop. I really tried to figure this out for several weeks but I need further guidance, a push in the right direction or direct help.
What I'm trying to do is to filter out some of the response to only view objects that contain specific data.
To do that, I'm using a filter where I want all products containing a specific value inside an array "product_option_values".
My first approach was to see if I could sort products having any values from the first array, and it worked. It filters just fine.
var filterSmall = jsonData.products.filter(fs => fs.associations.product_option_values);
My next approach was to get to my goal of filtering out products according to specific values inside this array. I tried many simple .(dot) combinations and pointing to [index] to access it without any luck. (I must add that I know how to access this from a specific product, but that way doesn't work when filtering).
I've also tried other approaches such as:
var filterSmall = jsonData.products.filter(fs => fs.associations["product_option_values", 0, "name"] === "S");
and other similar combinations.
This is a very shortened sample of the structure of "products" which in its full form consists of 20 products and far more values inside of it:
{
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
}
and here is a small and expanded sample from product_option_values:
{
"product_option_values": [
{
"id": 1,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
}
How do I proceed? Did I do anything correct or even close to it?
Perhaps I've been staring at this for too long.
Thanks in advance.
If you want to compare nested attributes you have to transform the objects (e.g. by using a map operation), so that the relevant attributes are easily accessible for a comparison. If you want to filter by product_option_value id, you could do something like this:
const jsonData = {
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
};
const sample = {
"product_option_values": [
{
"id": 22,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
};
const ids = sample.product_option_values.map((el) => String(el.id));
console.log(ids);
const filtered = jsonData.products.filter((fs) => fs.associations.product_option_values.map((e) => e.id).some((f) => ids.includes(f)));
console.log(filtered);

Extract value inside a multi-nested JSON Object with a "number" as a key name?

I'm trying to get the title of the first song in the JSON Object below but I have to go through a number as a key name.
Normally, we can do like this: title = top100.content.rank.title but it doesn't work with title = top100.content.1.title like the Object below.
My current solution is: title = Object.values(Object.values(top10.data)[1])[0].title which is very long and ugly. If you have a better way, please help me.
top100 = {
"info": {
"category": "Billboard",
"chart": "HOT 100",
"date": "2021-09-11",
"source": "Billboard-API"
},
"content": {
"1": {
"rank": "1",
"title": "Butter",
"artist": "BTS",
"weeks at no.1": "10",
"last week": "7",
"peak position": "1",
"weeks on chart": "15",
"detail": "up"
},
"2": {
"rank": "2",
"title": "Stay",
"artist": "The Kid LAROI & Justin Bieber",
"last week": "1",
"peak position": "1",
"weeks on chart": "8",
"detail": "down"
},
...
}
}
you can use the obj[key] syntax
top100['content'][1]['title']
you can access title of the first song in this way:
top100.content["1"].title

Filter My Array / JSON Data (including multi values) Based on Multiple Criteria in JavaScript?

The tricky part here is:
Some includes more than 1 value (like active substances: ["Morphine", "Fentanyl"])
Some values are repeating (retrospective: "1" for "true; ward_focused: "1" for true (again))
So the previous solutions here did not work for my project.
jsonData
[
{
"title": "Real-world evidence of high-cost drugs for metastatic melanoma",
"url": "https://.../Suppl_1/A5.1",
"filters": {
"retrospective": "1",
"ward_focused": "2",
"indication_focused": "1",
"active_substance": "2"
}
},
{
"title": "Real-world safety and tolerability of the recently commercialised palbociclib",
"url": "https://.../Suppl_1/A223.2",
"filters": {
"retrospective": "2",
"ward_focused": "1",
"indication_focused": "2",
"active_substance": "Palbociclib"
}
},
{
"title": "Cost-effectiveness of morphine versus fentanyl in managing ventilated neonates",
"url": "https://.../Suppl_1/A7.3",
"filters": {
"retrospective": "1",
"ward_focused": "1",
"indication_focused": "1",
"active_substance": ["Morphine", "Fentanyl"]
}
},
{
"title": "Chemical risk assessement in a quality control laboratory",
"url": "https://.../Suppl_1/A9.2",
"filters": {
"retrospective": "2",
"ward_focused": "2",
"indication_focused": "2",
"active_substance": "2"
}
},
{
"title": "The economic burden of metastatic breast cancer in Spain",
"url": "https://.../27/1/19",
"filters":{
"retrospective": "1",
"ward_focused": "1",
"indication_focused": "1",
"active_substance": "2"
}
}
]
query
const selectedFilters = {
retrospective: ["1"],
ward_focused: ["2"],
indication_focused: ["1"],
active_substance: []
};
The closest solution was when I've converted my data into an array and work on it as:
const filterArr = Object.values(selectedFilters).flat();
const output = myDataArray.filter(({filters}) => {
const objFilters = Object.values(filters).flat();
return filterArr.every(val => objFilters.includes(val));
})
console.log(output);
BUT it failed for the reason that the "1"s "true" and the "2"s for false are repeating many times in every profile.
I'm open to work on both as JSON and array for my data. Also I may modify the "1" -"2" structure for my boolean data types. You may also change the data structure if needed by removing the “filters” detail and working on one-depth.
Any help is appreciable. Best regards
The below snippet should filter your data using the js filter function and checking each possible filter against the filters obj
const json =[
{
"title": "Real-world evidence of high-cost drugs for metastatic melanoma",
"url": "https://.../Suppl_1/A5.1",
"filters": {
"retrospective": "1",
"ward_focused": "2",
"indication_focused": "1",
"active_substance": "2"
}
},
{
"title": "Real-world safety and tolerability of the recently commercialised palbociclib",
"url": "https://.../Suppl_1/A223.2",
"filters": {
"retrospective": "2",
"ward_focused": "1",
"indication_focused": "2",
"active_substance": "Palbociclib"
}
},
{
"title": "Cost-effectiveness of morphine versus fentanyl in managing ventilated neonates",
"url": "https://.../Suppl_1/A7.3",
"filters": {
"retrospective": "1",
"ward_focused": "1",
"indication_focused": "1",
"active_substance": ["Morphine", "Fentanyl"]
}
},
{
"title": "Chemical risk assessement in a quality control laboratory",
"url": "https://.../Suppl_1/A9.2",
"filters": {
"retrospective": "2",
"ward_focused": "2",
"indication_focused": "2",
"active_substance": "2"
}
},
{
"title": "The economic burden of metastatic breast cancer in Spain",
"url": "https://.../27/1/19",
"filters":{
"retrospective": "1",
"ward_focused": "1",
"indication_focused": "1",
"active_substance": "2"
}
}
];
function filterJson(filterObj) {
let hasRetrospective = false,
hasWardFocused = false,
hasIndicationFocused = false,
hasActiveSubstance = false;
const arr = json.filter(function (j) {
hasRetrospective = filterObj.retrospective.indexOf(j.filters.retrospective) > -1;
hasWardFocused = filterObj.ward_focused.indexOf(j.filters.ward_focused) > -1;
hasIndicationFocused = filterObj.indication_focused.indexOf(j.filters.indication_focused) > -1;
hasActiveSubstance = Array.isArray(j.filters.active_substance) ?
j.filters.active_substance.some(function (jf) {
return filterObj.active_substance.indexOf(jf) > -1;
}):
filterObj.active_substance.indexOf(j.filters.active_substance) > -1;
return hasRetrospective && hasWardFocused && hasIndicationFocused && hasActiveSubstance;
});
console.log(arr);
}
filterJson({
retrospective: ["1"],
ward_focused: ["1"],
indication_focused: ["1"],
active_substance: ["Morphine", "Fentanyl"]
});

Using underscore.js to find values in deeply nested JSON

I'm pretty new to Javascript, and I just learned about underscore.js. I have a deeply nested JSON object, and I need to use underscore to find key/value pairs, which I will then use to populate various HTML tables. If the structure was more shallow, using something like _.pluck would be easy, but I just don't know how to traverse past the first couple of nesting levels (i.e. surveyGDB, table, tablenames). The JSON object comes from an XML that is comprised of multiple nesting structures (mashed up from different database tables).
var JSONData =
"surveyGDB": {
"filename": "..\\Topo\\SurveyGeoDatabase.gdb",
"table": {
"tablename": [
{
"#text": "SurveyInfo\n ",
"record": {
"OBJECTID": "1",
"SiteID": "CBW05583-345970",
"Watershed": "John Day",
"VisitType": "Initial visit",
"SurveyInstrument": "Total Station",
"ImportDate": "2015-07-22T09:08:42",
"StreamName": "Duncan Creek",
"InstrumentModel": "TopCon Magnet v2.5.1",
"FieldSeason": "2015"
}
},
{
"#text": "QaQcPoints\n ",
"record": [
{
"OBJECTID": "1",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "tp",
"Count": "357"
},
{
"OBJECTID": "2",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "tb",
"Count": "92"
},
{
"OBJECTID": "3",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "to",
"Count": "8"
},
{
"OBJECTID": "4",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "bl",
"Count": "279"
},
{
"OBJECTID": "5",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "bf",
"Count": "18"
}
]
},
{
"#text": "QaQcPolygons\n ",
"record": [
{
"OBJECTID": "1",
"TIMESTAMP": "2015-07-22T09:43:08",
"SurveyExtentCount": "",
"WaterExtentCount": "",
"ChannelUnitsCount": "",
"ChannelUnitsUnique": ""
},
{
"OBJECTID": "2",
"TIMESTAMP": "2015-07-22T13:35:15",
"SurveyExtentCount": "1",
"WaterExtentCount": "1",
"ChannelUnitsCount": "21",
"ChannelUnitsUnique": "21"
}
]
}
]
}
}
}
For instance, I wanted all of the values for 'Code' in the 'QaQCPoints' table, so I tried:
var codes = _.flatten(_.pluck(JSONData.surveyGDB.table.tablename[1].record[0], "Code" ));
console.log(codes);
In the console, this returns an array with a length of 5, but with blank values.
What am I doing wrong?
I'd also rather search for the 'Code' values in the table based on something like the '#text' key value, instead of just using it's position in the object.
If I understood you correctly, you want to always search the record array within JSONData.surveyGDB.table.tablename array for some queries. This means you need to find the record based on some parameter and return something from the found record.
Do note that the record property is sometimes an array and sometimes an object (for table SurveyInfo) in your example so I'll assume you need to take this into account.
You can make a small function to extract data and handle both objects and arrays:
function extract(record, prop) {
if (Array.isArray(record)) {
return _.pluck(record, prop);
} else {
return record[prop];
}
}
Usage example:
I wanted all of the values for 'Code' in the 'QaQCPoints' table.
I'd also rather search for the 'Code' values in the table based on something like the '#text' key value, instead of just using it's position in the object.
To achieve this you first find a record using _.find, and then extract Code values from it using the method above:
var table = JSONData.surveyGDB.table.tablename;
// find an item that has `#text` property equal to `QaQcPoints`
var item = _.find(table, function(r) {
return r['#text'] === 'QaQcPoints';
});
// extract codes from the found item's record property
var code = extract(item.record, 'Code');
// output ["tp", "tb", "to", "bl", "bf"]
Running sample:
var JSONData = {
"surveyGDB": {
"filename": "..\\Topo\\SurveyGeoDatabase.gdb",
"table": {
"tablename": [{
"#text": "SurveyInfo",
"record": {
"OBJECTID": "1",
"SiteID": "CBW05583-345970",
"Watershed": "John Day",
"VisitType": "Initial visit",
"SurveyInstrument": "Total Station",
"ImportDate": "2015-07-22T09:08:42",
"StreamName": "Duncan Creek",
"InstrumentModel": "TopCon Magnet v2.5.1",
"FieldSeason": "2015"
}
}, {
"#text": "QaQcPoints",
"record": [{
"OBJECTID": "1",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "tp",
"Count": "357"
}, {
"OBJECTID": "2",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "tb",
"Count": "92"
}, {
"OBJECTID": "3",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "to",
"Count": "8"
}, {
"OBJECTID": "4",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "bl",
"Count": "279"
}, {
"OBJECTID": "5",
"TIMESTAMP": "2015-07-22T09:18:43",
"Code": "bf",
"Count": "18"
}]
}, {
"#text": "QaQcPolygons",
"record": [{
"OBJECTID": "1",
"TIMESTAMP": "2015-07-22T09:43:08",
"SurveyExtentCount": "",
"WaterExtentCount": "",
"ChannelUnitsCount": "",
"ChannelUnitsUnique": ""
}, {
"OBJECTID": "2",
"TIMESTAMP": "2015-07-22T13:35:15",
"SurveyExtentCount": "1",
"WaterExtentCount": "1",
"ChannelUnitsCount": "21",
"ChannelUnitsUnique": "21"
}]
}]
}
}
}
function extract(record, prop) {
if (Array.isArray(record)) {
return _.pluck(record, prop);
} else {
return record[prop];
}
}
var table = JSONData.surveyGDB.table.tablename;
var item = _.find(table, function(r) {
return r['#text'] === 'QaQcPoints';
});
console.dir(item);
var code = extract(item.record, 'Code');
console.log(code);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
You have a two stage problem. Stage one is figuring out which table is QaQcPoints. If that's always JSONData.surveyGDB.table.tablename[1], you're good.
The next stage is getting your data out. You can use native array manipulation most of the time (unless you're on really old browsers). So:
var table = JSONData.surveyGDB.table.tablename[1].record;
var codeArray = table.map(function(val) { return val.Code; });
Will do the trick.

backbone.js can't fetch data from url?

I had this working the other day, I don't know what I did differently but I can't fetch the data to add into my collection. From tutorials and the docs this code should work right?
var Player = Backbone.Model.extend({});
var PlayersCollection = Backbone.Collection.extend({
url: "data/players.json",
model: Player
});
var playersCollection = new PlayersCollection();
playersCollection.fetch({
success: function(players) {
alert('success')
},
error: function() {
alert('fail')
}
});
I get the error with that, I am thinking I am missing something VERY easy. Maybe it is my JSON, here is a look at it.
[
{
"name": "JELLY Bryant",
"team": "Ballaz",
"team_id": "1",
"number": "24",
},
{
"name": "Lebron James",
"team": "Miami Heat",
"team_id": "2",
"number": "6"
},
{
"name": "Dwayne Wade",
"team": "Miami Heat",
"team_id": "2",
"number": "3"
},
{
"name": "Michael Beasley",
"team": "Miami Heat",
"team_id": "2",
"number": "30"
},
{
"name": "Carmelo Anthony",
"team": "New York Knicks",
"team_id": "3",
"number": "15"
},
{
"name": "Ron Artest",
"team": "New York Knicks",
"team_id": "3",
"number": "5"
},
{
"name": "Karl Malone",
"team": "Los Angeles Lakers",
"team_id": "1",
"number": "33"
},
{
"name": "Damion Lillard",
"team": "Portland Trailblazers",
"team_id": "4",
"number": "3"
},
{
"name": "Westly Matthews",
"team": "Portland Trailblazers",
"team_id": "4",
"number": "55"
},
{
"name": "Wilt Chamberlin",
"team": "Los Angeles Lakers",
"team_id": "1",
"number": "17"
}
]
Inside the network tab (chrome dev tools) it does make a successful get on the json.
Request URL:http://localhost/FRESH/data/players.json
Request Method:GET
Status Code:200 OK (from cache)
I have to be missing something here lol. I had some large code that was getting data from hard coded collection then when I switched to the url method it wasn't working so I stripped it to the bare basics, so it's obviously something ticky-tack I am missing.
WOOOOOOW I saw that I added an extra comma to the end of the first json model "JELLY Bryant" and that solved it, I didnt think that was such a big deal, I just noticed it now.
Your server sends an invalid JSON : you have a dangling comma in the first object. Check http://json.org/ for what constitutes a valid JSON format and some online tools like http://jsonlint.com/ can give you a quick check.
Try
[
{
"name": "JELLY Bryant",
"team": "Ballaz",
"team_id": "1",
"number": "24"
}
]

Categories

Resources