Backbone.js collection where - backbone.js

I'm triyng to do a filter on a collection, the model is a Student like this:
{
code: "some code",
name: "some name",
course: {
course_code: "some code",
course_name: "course name"
}
}
if I try to do a filter like this:
var myVar = students.where({code: "some code"})
myVar will be filled with students according to the code and there are no problems. But how can I do filter by course_code?
I already tried:
var myVar = students.where({course: {course_code: "some code"}})
but I get nothing, if I try
var myVar = students.where({course.course_code: "some code"})
I get error.

let's assume you are finding students with course code 101.
var student_with_course_code = students.filter(function(student) {
return student.get('course').get('code') == 101;
});

var myVar = students.find(function(s) {return s.course.course_code == "some code"} )

Related

Filtering Array from contents of another Array

I have 2 arrays both with Strings.
let exclude = ["text 1", "text 2", "APP", "John"]
let array2 = ["this is text 1", "This is text 2", "This App is under development", "John is working on this project", "This is great"]
Im trying to filter any text that is contained in exclude from array2, caseInsensitive.
So in this example it should print "This is great"
Instead of using multiple lines for each filter like:
let filter = array2.filter{!$0.contains("APP")}
I tried:
var filter = array2.filter({exclude.contains($0)})
but it does not filter.
Any advice would be greatly appreciated
With "explicit" return and no $0.
let filtered = array2.filter { aString in
return !exclude.contains(where: { anExcludedString in
return aString.range(of: anExcludedString, options: .caseInsensitive) != nil
})
}
Why var filter = array2.filter({exclude.contains($0)}) didn't work?
First issue:
There is no case insensitive check.
Second issue:
You are using contains() on a [String], not a String. So it expect full equality between the two strings. So if array2 was ["APP"], it would have worked.
For instance if you had:
let exclude = ["text 1", "text 2", "APP", "John"]
let array2 = ["this is text 1", "This is text 2", "This App is under development", "John is working on this project", "This is great", "This APP is under development"]
let filtered = array2.filter { aString in
return !exclude.contains(where: { anExcludedString in
return aString.contains(anExcludedString)
})
}
Then "This APP is under development" would have been removed.
Now, going back to the initial answer, the way to check case insentive is to use range(of:options:).

Match prop values to lookup list with new (pretty) values

I'm using react and lodash. I have a prop type {props.value} that returns the result of "ThisIsFoo" and other results such as "ThisIsBar". I want to be able to map these results to elegantly display the output as "This is foo". Some sort of look up array will do the trick where I can list all the possible outcomes.
e.g.
var KeyMap = {
ThisIsFoo : "This is foo",
ThisIsBar : "This is Bar",
anotherOutcomeHere: "Another outcome here"
};
Ideally I want to get lodash to look at {props.value} match them to the key is it exists then output with its replacement.
var KeyMap = {
slowFit : "Slow Fit",
fastFit : "Fast Fit",
slowUnfit : "Slow Unfit",
fastUnfit : "Fast Unfit",
};
const str = props.label.replace(/slowFit|fastFit|slowUnfit|fastUnfit/gi, function(matched){
return KeyMap[matched];
});
This will create the keyMap from the values and then you can just match by the key:
var data = ["This is foo", "This is Bar", "Another outcome here"]
var keyMap = _.reduce(data, (r,c) => Object.assign(r, {[c.replace(/ /g, "")]: c}), {})
console.log("KeyMap: ", keyMap)
console.log(keyMap['ThisisBar'])
console.log(keyMap['Thisisfoo'])
// In your casse you would just display {keyMap[props.value]}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Keep Masterlist of Objects in Array, check array if it exists before adding a new object

The code below doesn't work as intended to. It never checks for the server in the master list. Am I doing something wrong?
var servers = [];
$.serverlist.addServers = function(jsonData) {
for (var server in servers) {
if (server["ID"] == jsonData["ID"]) {
// server exists, dont add, just update
} else {
//server doesnt exist, just add it
}
}
The jsonData I'm receiving is formatted like so:
{ "ID": 1, "something else": "Value", "another key": "Key Val" }
So when it goes into the array, the array states (if there were multiple added)
[
0:
{
"ID":1,
"something else": "Value",
"another key": "Key Val"
}
1:
{
"ID":2,etc...
}
]
Try testing the array length.
if( servers.length > 0 ){
// Server exist!
console.log("Append!");
}else{
// Doesn't...
console.log("Create the array.");
}
EDIT
For a specific object, this should do:
if( servers.indexOf(jsonData["ID"]) != -1 ){
// Data is in array
console.log("It's there.");
}else{
// Doesn't...
console.log("It's not there.");
}
2nd EDIT
I made a CodePen of what it should look like.
But I'm not sure about your data... It looks like DOM object format when you console log it.
I think it's different than a json or an object...
I made my example based on an array of objects.
Look at CodePen console.
var servers = [
{
"ID":1,
"something else": "Value",
"another key": "Key Val"
},
{
"ID":2,
"something else": "another Value",
"another key": "another Key Val"
},
{
"ID":3,
"something else": "Boring Value",
"another key": "Interesting!"
},
{
"ID":4,
"something else": "arrggg.",
"another key": "Yeah!"
}
];
for(i=0;i<servers.length;i++){
var temp = servers[i];
if (temp.ID== 3){
console.log("Found!");
break; // Exits the loop when found ID = 3
}else{
console.log("NOT fount yet... Still checking.");
}
}

Run a function that is stored in an array - Swift

I have recently started coding for iOS and using Swift. I am trying to build a small quiz app for practice. However, I am having an issue running a function that is stored in an array.
My question library swift file is as follows:
func getQuestionLibrary() -> NSArray {
var questionLibrary = [
[
"categoryName": "General Knowledge",
"functionName": generalknowledgeLibrary()
]]
As you can see it states the category and stores a function.
My code that works fine, uses this array (there are more entries) to dynamically create a list of categories to choose from. When a category is run it performs a segue and moves onto a view to display the categories.
If I hard code in the categories that app works great:
if playQuestionLibraryText == "General Knowledge" {
questionPack = generalknowledgeLibrary()
} else if playQuestionLibraryText == "Music" {
questionPack = musicLibrary()
} else if playQuestionLibraryText == "Film" {
questionPack = filmLibrary()
}
However, as the list is dynamic I would prefer it not to be hard coded.
Please can you assist me to allow the my code to search the array and run the function stored as functionName in the array when the correct category has been selected.
Thank you in advance.
The code:
"functionName": generalknowledgeLibrary()
Sets "functionName" to the result of calling the function.
Use:
"functionName": generalknowledgeLibrary
You are looking up a 'library' based on its name; use a Dictionary. Your 'library' is going to hold some stuff (as libraries are wont to do) and allow some behaviors - so capture it as an abstraction.
class Library { // maybe this is a 'questionPack'
// stuff in a library // that is okay, change the name
}
var libraryMap : [String:Library] =
["Music": Library(/*...*/),
"Film" : Library(/*...*/),
"General Knowledge" : Library(/*...*/)
// ....
]
if let library = libraryMap[playQuestionLibraryText] {
// do something with the library
}
i did a code to this question, using subscript
I created a class collection to manage your question. I believe the friend solution just remove () is more easy and correctly, but i created this class to complement my studies, because this I like enter here to try new solutions.
class QuestionCollection
{
struct QuestionItem {
var categoryName:String;
var function:()->Void //Here can add return type you need
}
private var dicCallbacks:[String:QuestionItem] = [String:QuestionItem]();
func add(categoryName:String, closure:()->Void //Here can add return type you need )
{
dicCallbacks[categoryName] = QuestionItem(categoryName: categoryName, function: closure);
}
subscript(categoryName:String)->()->Void //Here can add return type you need
{
get
{
if let callback = self.dicCallbacks[categoryName]
{
return callback.function;
}
return error;
}
set
{
dicCallbacks[categoryName] = QuestionItem(categoryName: categoryName, function: newValue);
}
}
func error()->Void
{
println("error try catch closure function")
}
}
How use this class
func musicTest()
{
println("test Music");
}
func musicGK()
{
println("test Music");
}
func musicFilm()
{
println("test Music");
}
var questionCollection = QuestionCollection();
questionCollection["Music"] = musicTest
questionCollection["General Knowledge"] = musicGK
questionCollection["Film"] = musicFilm
questionCollection["Music"]();
questionCollection["General Knowledge"]();
questionCollection["Film"]();
Sorry for slow reply. I changed my code as this works instead and I am happy with how it works.
The questions in the future will be populated via the internet via a loop.
struct Question {
var categoryName : String
var questionTitle : String
var answerA : String
var answerB : String
var answerC : String
var answerD : String
var correct : String
}
public struct QuestionLibrary {
var questions: [Question]
}
let QuizQuestions =
QuestionLibrary(
questions: [
Question(
categoryName: "General Knowledge",
questionTitle: "Question 1",
answerA: "A", answerB: "B", answerC: "C", answerD: "D", correct: "D"),
Question(
categoryName: "Music",
questionTitle: "Question 2",
answerA: "A", answerB: "B", answerC: "C", answerD: "D", correct: "A"),
Question(
categoryName: "Film",
questionTitle: "Question 3",
answerA: "A", answerB: "B", answerC: "C", answerD: "D", correct: "B")
])
My code then to retrieve questions based on the category is:
let questionLibrary = QuizQuestions.questions
var questionPack: Array<Question>?
questionPack = questionLibrary.filter({c in c.categoryName == "Music" })
I then select a random question
let question = questionPack![randomNumber]
And to display the question text is
question.questionTitle
So, my earlier question was about running functions in an array which I learnt I didn't need to do. But least I've answered so it might have others who need similar code :)

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