JavaScript multidimensional get value without looping - javascript

I've got a question,
I've got an array in Javascript that looks like this:
var plans = [{
'advanced':[{
'price':'10',
'name':'Advanced'
}],
'basic':[{
'price':'20',
'name':'Basic'
}]
}];
And there's a variable called plan, this could be advanced or basic etc. Now I want to display the price from the array that corresponds with the variable plan. How do I get the price?
I've tried things like:
plans.advanced.price
plans['advanced']['price']
plans[0].advanced['0'].price
plans[0]['advanced']['0']['price']
PS: I am originally A PHP developer, maybe my PHP influence is blocking the correct thoughts, i dont know...

Access it like this: plans[0].advanced[0].price
That's the wrong way to be going about it though; just use JavaScript objects:
var plans = {
advanced: {
price: '10',
name: 'Advanced'
},
basic: {
price: '20',
name:' Basic'
}
};
Then you can access it using plans.advanced.price, which is much more clear.
Note that plans.advanced.price is the same as plans['advanced']['price'] in JavaScript, there is no difference.
Arrays in JavaScript are just glorified objects - as such there is no such thing as "associative arrays" in JavaScript, objects perform the same thing as associative arrays in PHP.

you have some extra array cruft, where you have arrays with one item in them instead of just having the object.
var plans = {
advanced: {
price: '10',
name: 'Advanced'
},
basic: {
price: '20',
name:' Basic'
}
};
if you have var plan ="advanced" you can just do plans[plan].price
if you NEED the current structure with the arrays then it is essentially the same thing but
var plan ="advanced"
plans[0][plan][0].price
hope that helps

Related

Not understanding mongoose schema array syntax

I'm having trouble wrapping my head around the below syntax in a mongoose schema.
tokens:[{
token:{
type: 'String',
required: true
}
}]
Normally when I want to add objects to arrays I would just push the object. That includes if I want to push an object with an internal object to said array like the example below.
let obj =[]
obj.push({name: 'dirk', age: 24})
obj.push({name: 'chris', age:29, clothes: {shirt: 'black', pants: 'jeans'}, height: '6ft'})
So im confused in mongoose as to why I need this syntax [{}] to use an array?
Ok I'll try to explain this as best I can. In basic JavaScript, an array is just a bucket of "stuff" for lack of better words. What that means is, you could have something like this:
let myList = []
myList.push({name: "John Doe", age: 20})
myList.push({car: {make: "Honda", model: "Accord"}})
myList.push({menu_items: ["item 1", "item 2", "item 3"]})
And JavaScript won't really care right? As far as it's concerned, you haven't done anything wrong because you technically did the correct thing, put some object into a list that can hold whatever you want.
Mongoose, which is an ORM (check out the term if you haven't heard of it before), requires things be a little more strict. Remember that Mongoose is trying to map documents from the Mongo database to this "Object" that should be standard and readable from any point in the code the same what. So in the example in your question listed above:
tokens:[{
token:{
type: 'String',
required: true
}
}]
you are saying to Mongoose that it should expect tokens to contain a list of token objects that have a certain design to them. Now, when you want to add more token objects to the tokens list, you can do something like this:
token = {
// YOUR CORRECT TOKEN DATA
}
tokens.push(token);
If you tried to do something like this instead:
token = {
// RANDOM WRONG DATA
}
tokens.push(token);
Mongoose wouldn't take kindly to it because you are violating the constraints you told Mongoose to keep in affect. If you start throwing any: [{}] into the mix, you are telling Mongoose that any old object will do for that list. This is, in my opinion, very dangerous to do because if you have two types of objects in your list:
var schema1 = new Schema({
name: String,
age: { type: Number, min: 18, max: 65 },
living: Boolean
})
var schema2 = new Schema({
name: String,
age: { type: Number, min: 18, max: 65 },
breed: Boolean
})
and you were working with a list that combined these two objects, if you tried to grab say breed from the schema1 type object, you would either get an error or an odd value that could break your code. So Mongoose strictly types the objects you are pushing to a list, unless you use something like Mixed or any. Here's a link to the documentation that may help explain a bit as well
https://mongoosejs.com/docs/schematypes.html#arrays
If this doesn't make sense or I explained it poorly or answered the wrong question please comment and I'll fix it to explain as best I can.
Happy coding :-)

How to optimize performance of searching in two array of object

There are two array of objects one from database and one from csv. I required to compare both array object by their relative properties of Phones and emails and find duplicate array among them. Due to odd database object structure I required to compare both array with Javascript. I wanted to know what is the best algorithm and best way of compare and find duplicates?
I explain simple calculations.
There are 5000 contacts in my database and user may upload another 3000 contacts from csv. Everytime we requires to find duplicate contacts from database and if they find then it may overwrite and rest should be insert. If I compare contact row by row then it may loop 5000 database contacts x 3000 csv contacts = 15000000 time traverse.
This is my present scenario I face due to this system goes stuck. I require some efficient solution of this issue.
I develop the stuff in NodeJS, RethinkDB.
Database object structure exactly represent like that way and it may duplicate entry of emails and phones in other contacts also.
[{
id: 2349287349082734,
name: "ABC",
phones: [
{
id: 2234234,
flag: true,
value: 982389679823
},
{
id: 65234234,
flag: false,
value: 2979023423
}
],
emails: [
{
id: 22346234,
flag: true,
value: "test#domain.com"
},
{
id: 609834234,
flag: false,
value: "test2#domain.com"
}
]
}]
Please review fiddle code, if you want: https://jsfiddle.net/dipakchavda2912/eua1truj/
I have already did indexing. The problem is looking very easy and known in first sight but when we talk about concurrency it is really very critical and CPU intensive.
If understand the question you can use the lodash method differenceWith
let csvContacts = [] //fill it with your values;
let databaseContacts = .... //from your database
let diffArray = [] //the non duplicated object;
const l = require("lodash");
diffArray = l.differenceWith(csvContact,
databaseContacts,
(firstValue,secValue)=>firstValue.email == secValue.email

JavaScript array of objects conversion

I wasnt exactly sure what i should name this question so feel free to edit the title.
I am running an angular application and using node.js combinded with express and sequlize (for my ORM)
Now as many of you may know when your working with an ORM you want to collect Objects inside of another Object for instance a user object might have a country object inside of it as shown below:
user = {id: 222, username: 'Marc', name: 'Marc Ras', country: {id: 1, code: 'DK', name: 'Denmark'}}
Now this is great. binding all of these objects together makes it alot easier to work with in the frontend.
However the other way around is rather annoying.
Lets for the purpose of demonstration take the above object. but lets add a property an array of items
user.items = [{id: 1 , name:'item1'}, {id: 2, name: 'item2'}]
Now if i wish to add this object to my database i would send the combined object to my express route:
var user = {
id: 222,
username: 'Marc',
name: 'Marc Ras',
country: {id: 1, code:'DK', name: 'Denmark'}
items: [
{id: 1, name: 'item1'},
{id: 2, name: 'item2'}
]
}
And now things get abit messy
Say for instance you have the following table:
user_has_items
Each record in this has an id, user_id, item_id
Now in order to make sure that the objects inside user.items match the table you will now have to make code gymnastic by making loops and editing the above object.
Like as such:
user.items.forEach(function (x) {
x.item_id = x.id;
x.id = null; // To make sure the database does not set the id (since this is auto inc)
x.user_id = user.id;
})
Note the above is of course an example it gets more complicated the bigger your object is!
This process leads to messy code (atleast in my opinion) and since this is not the first time i encounter this problem i was wondering if any of you had any solutions as to what you might do to make this process easier?
I have been looking at lodash to see if they had some way of doing this but sadly i could not find anything that made this easy

sorting javascript array slice

In trying to create a sortable table, I am sorting the underlying array of data:
var g = [
[ 'First Name', 'Last Name', 'Id', 'Age'],
[ 'Joe', 'Blogs', '1', 24],
[ 'Fred', 'Frog', '2', 18],
];
I want to sort everything except the header.
g = g.sort(mycomparison);
is no good, though I could change the comparison routine to always put element[0] in front of everything else.
Instead, I would like to sort everything except the header. The following seems to do what I want, but I wanted to know if there is a better way to express this in javascript. I want to sort the last n-1 elements.
g = g.slice(0,1).concat(g.slice(1,g.length-1).sort(mycomparison))
If you are interested in another way which looks a bit tidier, see this following underscore.js way:
g = [].concat(_.first(g), _sort(_.tail(g), mycomparison ));
Using underscore does not help improving performance but it just simplifies and makes your code a bit more readable. From the example above, I believe it makes sense to people who even don't usually use underscore.
It's straightforward and semantic so people read it and understand instantly that it splits the first, and the rest of array g, sort the rest and re-join them. (To me it looks more readable than vanilla JavaScript)

Efficient Sorted Data Structure in JavaScript

I'm looking for a way to take a bunch of JSON objects and store them in a data structure that allows both fast lookup and also fast manipulation which might change the position in the structure for a particular object.
An example object:
{
name: 'Bill',
dob: '2014-05-17T15:31:00Z'
}
Given a sort by name ascending and dob descending, how would you go about storing the objects so that if I have a new object to insert, I know very quickly where in the data structure to place it so that the object's position is sorted against the other objects?
In terms of lookup, I need to be able to say, "Give me the object at index 12" and it pulls it quickly.
I can modify the objects to include data that would be helpful such as storing current index position etc in a property e.g. {_indexData: {someNumber: 23, someNeighbour: Object}} although I would prefer not to.
I have looked at b-trees and think this is likely to be the answer but was unsure how to implement using multiple sort arguments (name: ascending, dob: descending) unless I implemented two trees?
Does anyone have a good way to solve this?
First thing you need to do is store all the objects in an array. That'll be your best bet in terms of lookup considering you want "Give me the object at index 12", you can easily access that object like data[11]
Now coming towards storing and sorting them, consider you have the following array of those objects:
var data = [{
name: 'Bill',
dob: '2014-05-17T15:31:00Z'
},
{
name: 'John',
dob: '2013-06-17T15:31:00Z'
},
{
name: 'Alex',
dob: '2010-06-17T15:31:00Z'
}];
The following simple function (taken from here) will help you in sorting them based on their properties:
function sortResults(prop, asc) {
data = data.sort(function(a, b) {
if (asc) return (a[prop] > b[prop]);
else return (b[prop] > a[prop]);
});
}
First parameter is the property name on which you want to sort e.g. 'name' and second one is a boolean of ascending sort, if false, it will sort descendingly.
Next step, you need to call this function and give the desired values:
sortResults('name', true);
and Wola! Your array is now sorted ascendingly w.r.t names. Now you can access the objects like data[11], just like you wished to access them and they are sorted as well.
You can play around with the example HERE. If i missed anything or couldn't understand your problem properly, feel free to explain and i'll tweak my solution.
EDIT: Going through your question again, i think i missed that dynamically adding objects bit. With my solution, you'll have to call the sortResults function everytime you add an object which might get expensive.

Categories