sorting javascript array slice - javascript

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)

Related

How to format javascript array with lots of values

In javascript, I am creating an array with some values in it. The list of values is relatively long, and results in the single line of code appearing on two lines on most screens. For example, the line of code is:
var fieldNames = ['firstName', 'lastName', 'phoneNumber', 'emailAddress', 'hotelName', 'roundTrip', 'origin', 'departureDate', 'departureTime', 'returnDate', 'returnTime'];
Is there a preferred way to format this line so it's more readable? Should each value in the array be on its own line?
If the goal is more readable code, then putting each element separately on its own line works well.
For example, as is, if you make a change to an element in the array and commit to git, the whole line will show up as being changed in the diff. It is difficult for others to see exactly which element changed.
If each element is on its own line, and you make a change to an element then commit to git, then only the line with the changed element will show up in the diff. It is then obvious which element was changed.
This is what I usually do:
var fieldNames = [
'firstName', 'lastName', 'phoneNumber', 'emailAddress', 'hotelName',
'roundTrip', 'origin', 'departureDate', 'departureTime', 'returnDate',
'returnTime'
];
This is what I do. This may or may not be a good idea.
At least for me, it helps me to understand where the array starts and stops and what variable it belongs to.
We use require.js in our project and sometimes it happens that a module requires a lot of dependencies so our code looks like this:
require([
module1,
module2,
module3,
module4,
module5,
module6
], function(
module1_obj,
module2_obj,
module3_obj,
module4_obj,
module5_obj,
module6_obj
){
...
});
Because we have to define 2 lists that are really long we format it as a column, 1 item in one line, this way when we delete a dependency we can easily delete it in both columns and see that both have identical count of items.
Clarification: first array in require.js defines dependencies and the second gives an object to use of that dependency that is the reason why there are two.
Benefits of not placing any item in first line
var foo = [ // <-- Not having an element on this line.
1,
2,
3
];
Is that then the array is defined in the same fashion as object is usually:
var bar = {
iAmAProperty: "YAY"
};
And in version control you can clearly see if the content of object/array is edited or the name of the object/array
var fieldNames = ['firstName', 'lastName', 'phoneNumber', 'emailAddress',
'hotelName', 'roundTrip', 'origin', 'departureDate', 'departureTime',
'returnDate', 'returnTime'];

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.

JavaScript multidimensional get value without looping

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

Aggregation the data from mongodb, map reduce or any other ways?

Well i am struggling with the aggregation problems. I thought the easiest way to solve problem is to use map reduce or make separate find queries and then loop through with the async library help.
The schema is here:
db.keyword
keyword: String
start: Date
source: String(Only one of these (‘google’,’yahoo’,’bing’,’duckduckgo’) )
job: ref db.job
results: [
{
title: String
url: String
position: Number
}
]
db.job
name: String
keywords: [ String ]
urls: [ String ]
sources: [ String(‘google’,’yahoo’,’bing’,’duckduckgo’) ]
Now i need to take the data to this form:
data = {
categories: [ 'keyword1', 'keyword2', 'keyword3' ],
series: [
{
name: 'google',
data: [33, 43, 22]
},
{
name: 'yahoo',
data: [12, 5, 3]
}
]
}
Well the biggest problem is that the series[0].data array is made of really difficult find, matching the db.job.urls against the db.keyword.results.url and then get the position.
Is there any way to simplify the query_? I have looked through many of the map reduce examples, but I cant find the correct way what data to map and which to reduce.
It looks as though you are trying to combine data from two separate collections (keyword and job).
Map Reduce as well as the new Aggregation Framework can only operate on a single collection at a time.
Your best bet is probably to query each collection separately and programmatically combine the results, saving them in whichever form is best suited to your application.
If you would like to experiment with Map Reduce, here is a link to a blog post written by a user who used an incremental Map Reduce operation to combine values from two collections.
http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/
For more information on using Map Reduce with MongoDB, please see the Mongo Documentation:
http://www.mongodb.org/display/DOCS/MapReduce
(The section on incremental Map Reduce is here: http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-IncrementalMapreduce)
There are some additional Map Reduce examples in the MongoDB Cookbook:
http://cookbook.mongodb.org/
For a step-by-step walkthrough of how a Map Reduce operation is run, please see the "Extras" section of the MongoDB Cookbook recipe "Finding Max And Min Values with Versioned Documents" http://cookbook.mongodb.org/patterns/finding_max_and_min/
Hopefully the above will give you some ideas for how to achieve your desired results. As I mentioned, I believe that the most straightforward solution is simply to combine the results programmatically. However, if you are successful writing a Map Reduce operation that does this, please post your solution, so that the Community may gain the benefit of your experience.

Problem with ordering headings in a sorted list

I am building a web application in which I build a sorted list out of an object like this:
{head: {subhead: [list_items], subhead: [list_items]}, head: {subhead: [list_items]}}.
My problem is that I have to ensure the headings and subheading always follow in a certain order. This is complicated by the fact that headings and subheadings that may be added later on also need to follow this order. So the only way I could think to inform the parser of the order would be to give it some data like this:
{heads: [head1, head2, head3], subheads: {head1: [subhead1_1, subhead1_2], head2: [subhead2_1, subhead2_2, subhead2_3]}},
but that strikes me as overly verbose and repeating data that would be in the original data structure.
You might as well use an array (or your own structure) for this since you want it to be ordered. Your own structure might look like:
function Head(name) {
this.name = name;
this.arr = [];
}
So instead of the structure:
var thing = {
food: {fruit: [apples, oranges], vegetables: [carrots, peas]},
animals: {domestic: [cat, dog], wild: [lion, bear]}
}
You might do:
var thing = [new Head('food'), new Head('animals')]
Then:
thing[0].arr.push('apples');
thing[0].arr.push('oranges');
etc.
Of course you don't have to make a class, since you can actually attach properties to arrays in javascript. But making the datastructure would be a bit more of a pain.

Categories