Sorting specific structure objects by their properties - javascript

So I have such dummy data object:
var Products = {
'sku': {n:'Trampolines rain covers',v:'7Ft',l:'http://www.google.com',i:['media/cache/search/media/1151-Trampoline-jumping-mat.png','media/cache/searchSuggest/media/1151-Trampoline-jumping-mat.png','#'],r:['4','3.2','0','1','3','0','0'],p:['7.99','9.99'],d:'Some kind of description',f:'Features',b:'Benefits',s:'Specifications'},
'sku2': {n:'Icon cast adjustable dumbbell',v:'10kg',l:'http://www.google.com',i:['media/cache/search/media/1167-Single-dumbbell.png','media/cache/searchSuggest/media/1167-Single-dumbbell.png','#'],r:['4','2.5','1','0','1','0','2'],p:['7.99','9.99'],d:'Some kind of description',f:'Features',b:'Benefits',s:'Specifications'},
'sku3': {n:'Trampolines safety net & bases',v:'6Ft',l:'http://www.google.com',i:['media/cache/search/media/1195-Trampoline-safety-net.png','media/cache/searchSuggest/media/1195-Trampoline-safety-net.png','#'],r:['3','3.5','1','0','1','0','1'],p:['7.99','9.99'],d:'Some kind of description',f:'Features',b:'Benefits',s:'Specifications'},
'sku4': {n:'Andico spring for trampolines',v:'5.5 inch',l:'http://www.google.com',i:['media/cache/search/media/1166-Trampoline.png','media/cache/searchSuggest/media/1166-Trampoline.png','#'],r:['3','3.5','1','0','1','0','1'],p:['7.99','9.99'],d:'Some kind of description',f:'Features',b:'Benefits',s:'Specifications'}
}
and then I have array of skus
var skus = ['sku','sku3','sku4'];
My task is to sort this array by sku object property n (which is string / product title of multi words) alphabetically ascending.
I know for that I should use .sort(ref) function, but I wonder with function inside, something like:
skus.sort(function(a,b) { });
But I can't find out how to formulate the inner function to make the job done. Maybe I should do this in another way?

You're very nearly there. Within the function, you use a and b to look up the entries on your Products object, so you can compare entries:
skus.sort(function(a, b) {
var an = Products[a].n,
bn = Products[b].n;
if (an === bn) {
return 0;
}
return an < bn ? -1 : 1;
});

Related

Get "leaderboard" of list of numbers

I am trying to get a kind of "leaderboard" from a list of numbers. I was thinking of making an array with all the numbers like this
var array = [];
for (a = 0; a < Object.keys(wallets.data).length; a++) { //var wallets = a JSON (parsed) response code from an API.
if (wallets.data[a].balance.amount > 0) {
array.push(wallets.data[a].balance.amount)
}
}
//Add some magic code here that sorts the array into descending numbers
This is a great option, however I need some other values to come with the numbers (one string). That's why I figured JSON would be a better option than an array.
I just have no idea how I would implement this.
I would like to get a json like this:
[
[
"ETH":
{
"balance":315
}
],
[
"BTC":
{
"balance":654
}
],
[
"LTC":
{
"balance":20
}
]
]
And then afterwards being able to call them sorted descending by balance something like this:
var jsonarray[0].balance = Highest number (654)
var jsonarray[1].balance = Second highest number (315)
var jsonarray[2].balance = Third highest number (20)
If any of you could help me out or point me in the right direction I would appreciate it greatly.
PS: I need this to happen in RAW JS without any html or libraries.
You should sort the objects before making them a JSON. You can write your own function or use a lambda. See this [https://stackoverflow.com/questions/1129216/sort-array-of-objects-by-string-property-value]
Since you are dealing with cryptocurrency you can use the currency-code as a unique identifier.
Instead of an array, you can define an object with the currency as properties like this:
const coins = {
ETH: [300, 200, 500],
BTC: [20000, 15000, 17000]
}
then you can access each one and use Math.max or Math.min to grab the highest / lowest value of that hashmap. E.G. Math.max(coins.BTC)
And if you need to iterate over the coins you have Object.keys:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Thank you all for your answer. I ended up using something like:
leaderboard = []
for (a = 0; a < Object.keys(wallets.data).length; a++) {
if (wallets.data[a].balance.amount > 0) {
leaderboard.push({"currency":wallets.data[a].balance.currency, "price":accprice}) //accprice = variable which contains the value of the userhold coins of the current coin in EUR
}
}
console.log(leaderboard.sort(sort_by('price', true, parseInt)));

How to sort records by sequence instead of name in Odoo OCA widget web_widget_x2many_2d_matrix?

I already try with no success to sort by sequence a dict of records by jquery I don't know where sorted again by name.
I ask the community on git but nobody answer me, I'm trying to sort by odoo sequence. using modules web_widget_x2many_2d_matrix, and sale_order_variant_mgmt
I modify python code, and if I debug the list of records the sort is the intended, but when the javascript code is loaded, it sorted by name and cant debug where the problem is
#api.onchange('product_tmpl_id')
def _onchange_product_tmpl_id(self):
self.variant_line_ids = [(6, 0, [])]
template = self.product_tmpl_id
context = self.env.context
record = self.env[context['active_model']].browse(context['active_id'])
if context['active_model'] == 'sale.order.line' or context['active_model'] == 'sale.order.line_group': #TODO check this modify for lentex group_sale_lines module
sale_order = record.order_id
else:
sale_order = record
num_attrs = len(template.attribute_line_ids)
if not template or not num_attrs:
return
line_x = template.attribute_line_ids[0]
line_y = False if num_attrs == 1 else template.attribute_line_ids[1]
lines = []
for value_x in line_x.value_ids.sorted(key=lambda r: r.sequence):
for value_y in line_y and line_y.value_ids.sorted(key=lambda r: r.sequence) or [False]: #I modify this and in python the sort is the intended, but not in JS
# Filter the corresponding product for that values
values = value_x
if value_y:
values += value_y
product = template.product_variant_ids.filtered(lambda x: not(values - x.attribute_value_ids))[:1]
order_line = sale_order.order_line.filtered(lambda x: x.product_id == product)[:1]
lines.append((0, 0, {
'product_id': product,
'disabled': not bool(product),
'value_x': value_x,
'value_y': value_y,
'product_uom_qty': order_line.product_uom_qty,
}))
self.variant_line_ids = lines
I think the problem is here
// get x axis values in the correct order
get_x_axis_values: function()
{
return _.keys(this.by_x_axis); //I think here is where the order is defined
},
// get y axis values in the correct order
get_y_axis_values: function()
{
return _.keys(this.by_y_axis); //I think here is where the order is defined
},
It looks like your sorting the dictionary, but dictionaries don't have or maintain an order.
Create a temporary list to hold the key values in order based on the value then iterate through that list to handle the dictionary values in the desired order.
alternatively you could use an "OrderedDict" in python
from collections import OrderedDict

JavaScript database correlation

I've been trying to 'correlate' between user picked answers and an object property name so that if the two matches then it will display what is inside.
My program is a recipe finder that gives back a recipe that consists of the ingredients the user picked.
my code currently looks like:
//property are the ingredients and the value are the recipes that contain those ingredients. The map is automatically generated
``var map = {
"pork" : [recipe1, recipe2, ...],
"beef" : [],
"chicken" :[],
}
//this gets the user pick from the dom
var cucumber = specificVegetable[7];
var lemon = specificFruits[0];
//Then this code finds the intersection of the recipe(recipes that use more than one ingredients)
function intersect(array1, array2)
{
return array1.filter(function(n) {
return array2.indexOf(n) != -1
});
}
var recipiesWithLemon = map["lemon"]; **// makes the lemon object is map**
var recipiesWithCucumber = map["cucumber"]; **// makes the cucumber object in map**
//Here is where I am stuck
function check(){
var both = intersect(recipiesWithLemon, recipiesWithCucumber);
if ( cucumber.checked && lemon.checked){
for (var stuff in map){
if(stuff="cucumber" && stuff="lemon"){
return both;
}
}
}
}
check();
so basically what I tried to do was I made my intersect and then if user pick is lemon and cucumber then look at the properties in the map object. if the name of the property equals to the exact string then return both. That was the plan but the code does not work and I'm not sure how to fix it.
My plan is to write code for every possible outcome the user may makes so I need to find the correlation between the user pick and the map which stores the recipe. I realize this is not the most effective way but I'm stumped on how to do it another way.
Thanks for the help.
Im using the open source project jinqJs to simplify the process.
I also changed your map to an array of JSON objects. If you must have the map object not as an array, let me know. I will change the sample code.
var map = [
{"pork" : ['recipe1', 'recipe2']},
{"beef" : ['recipe3', 'recipe4']},
{"peach" :['recipe5', 'recipe6']},
{"carrot" :['recipe7', 'recipe8']}
];
var selectedFruit = 'peach';
var selectedVeggie = 'carrot';
var selections = [selectedFruit, selectedVeggie];
var result = jinqJs().from(map).where(function(row){
for(var f in row) {
if (selections.indexOf(f) > -1)
return true;
}
return false;
}).select();
document.body.innerHTML += '<pre>' + JSON.stringify(result, null, 2) + '</pre><br><br>';
<script src="https://rawgit.com/fordth/jinqJs/master/jinqjs.js"></script>

How to sort a set of XML results based on bid value?

I'm probably missing missing something real simple here.
I've an XML feed. I know how to parse the XML itself, but how do I turn, say, an array of objects like:
[
{bid:"0.001", title:'test title', description:'test description'},
{bid:"0.025", title:'why are you', description:'still reading'}
]
..into an array where I know that array[0] will fetch me the XML result object with the highest bid - meaning, I need to scan through the objects inside and sort them by highest bid.
I've messed around with jquery's filter but I can't get it to work.
Sort an array using custom sorting function:
your_array.sort(sortByBid);
sortByBid = function(a, b) {
var a_bid = parseFloat(a.bid);
var b_bid = parseFloat(b.bid);
if (a_bid === b_bid) {
return 0;
}
return (a_bid > b_bid ? 1 : -1);
}

How do i reverse JSON in JavaScript?

[
{"task":"test","created":"/Date(1291676980607)/"},
{"task":"One More Big Test","created":"/Date(1291677246057)/"},
{"task":"New Task","created":"/Date(1291747764564)/"}
]
I looked on here, and someone had the same sort of question, but the "checked" correct answer was that it will be different on IE if the item is deleted, which would be fine. My issue is, those items above are stored, but when i go and grab them, iterate, and return, the items are reversed and the created is at the 0 index and task is at 1. Also, i need to return this as JSON.
Here is my basic JS (value == an int the user is passing in):
outputJSON = {};
for(x in json[value]){
outputJSON[x] = _objectRevival(json[value][x]);
}
return outputJSON;
That returns:
created: Mon Dec 06 2010 15:09:40 GMT-0800 (Pacific Standard Time)
task: "test"
The order of the properties of an object is undefined. It is not possible to force them in a specified order. If you need them in a specific order, you can build this structure reliably using arrays:
var values = [
[["task", "test"], ["created", "/Date(1291676980607)/"]],
[["task", "One More Big Test"], ["created", "/Date(1291677246057)/"]],
[["task", "New Task"], ["created", "/Date(1291747764564)/"]]
];
Then you can iterate over your structure like this:
for (var i = 0; i < values.length; i++) {
for (var k = 0; k < values[i]; k++) {
// values[i][k][0] contains the label (index 0)
// values[i][k][1] contains the value (index 1)
}
}
To enforce a particular order for your output just replace json[value] in your for loop with an array of the object properties in the order you want to display them, in your case ["task", "created"].
The problem is that javascript objects don't store their properties in a specific order. Arrays on the other do (hence why you can get something consistent from json[0], json[1], json[2]).
If your objects will always have "task" and "created", then you can get at them in any order you want.
json[value]["task"]
and
json[value]["created"]
Update:
This should work with your existing code.
Before sending the json object:
var before = [
{"task":"test","created":"/Date(1291676980607)/"},
{"task":"One More Big Test","created":"/Date(1291677246057)/"},
{"task":"New Task","created":"/Date(1291747764564)/"}
];
var order = [];
for (var name in before[0]) {
order.push(name); // puts "task", then "created" into order (for this example)
}
Then send your json off to the server. Later when you get the data back from the server:
var outputJSON = {};
for (var x in order) {
if (order.hasOwnProperty(x)) {
outputJSON[order[x]] = _objectRevival(json[value][order[x]]); // I'm not sure what _objectRevival is...do you need it?
}
}
return outputJSON;
var items = ["bag", "book", "pen", "car"];
items.reverse();
This will result in the following output:
car , pen, book, bag
Even if you have JSON array it will reverse.

Categories

Resources