0

I have four variables of type integer -

var tip_1, tip_2, tip_3, tip_4;

The value of these variables are getting fill by some other logic which is always between 1 to 10. I need to maintain a hash with variable name as "key" and value as "value" by following these rules -

  1. The variable with MAX value should be the first element in the hash and so on. e.g. if tip_1 = 4, tip_2 = 1, tip_3 = 2, tip_4 = 10 then hash should be something like, Hash = {tip_4, 10} {tip_1, 4} {tip_3, 2} {tip_1, 1}

  2. In case of tie following order should be considered - tip_1 > tip_2 > tip_3 > tip_4;

1
  • "first element in the hash" ?? Sure you're not referring to an array? (Hash's don't have first element, second element, etc) Commented Jun 14, 2010 at 5:15

2 Answers 2

2

You can always build your custom objects to retain all information instead of encoding them in indices. Makes sorting easier too.

function Tip(type, value) {
    this.type = type;
    this.value = value;
}

var tips = [];

tips.push(new Tip(3, 4));
tips.push(new Tip(2, 4));
tips.push(new Tip(1, 3));
tips.push(new Tip(4, 10));

tips.sort(function(a, b) {
    // sort first by value, and if equal, then by type (index)
    return (b.value - a.value) || (a.type - b.type);    
});

console.log(tips); // 4=>10​, 2=>4, 3=>4, 1=>3​​​​​​​​​​​​​​​​​

Updated the example.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi. The logic and this approach works fine if I would take an array as your code. But I am bound to use a hash (Prototype). I am not able to implement the same logic for hash. So, the hash I have is something like - h = new Hash(); h.set("tip_1", 4); h.set("tip_2", 2); h.set("tip_3", 1); h.set("tip_4", 2); The default order is tip_1>tip_2>tip_3>tip_4 (in case of tie) After, implementing the logic result Hash should be as - result - [{tip_1, 4}, {tip_2, 2}, {tip_4, 2}, {tip_3, 1}]
You can't order the contents of a hash all by itself. Read the first line of docs on Prototype's Hash - "it can not guarantee consistent order its elements when iterating". You have to either switch to arrays, or write a wrapper that contains the Hash and also maintains the sorted keys in another array.
@Saurabh - You have to use an array to maintain order. In the example you have given, you are using an array as well - an array of objects - [{tip_1, 4}, {tip_2, 2}, {tip_4, 2}, {tip_3, 1}]. You can write a custom sort method that takes in the hash, and returns an array of sorted objects, but that sorted array will not be the same as your original Hash, which basically means you have two separate representations of your data. If that's acceptable then look at @granf's solution, although it needs a little modification to work properly.
0

It's a lot easier to do if you make a real array out of your tips:

var tip_1 = 4, tip_2 = 1, tip_3 = 2, tip_4 = 10;

// create an array so we can sort it
var tips = [
  { key: 'tip_1', value: tip_1 }, 
  { key: 'tip_2', value: tip_2 }, 
  { key: 'tip_3', value: tip_3 }, 
  { key: 'tip_4', value: tip_4 }, 
];

tips.sort(function (a, b) {
  // sort value descending
  if (a.value < b.value) return 1;
  if (a.value > b.value) return -1;
  // if the values are equal, sort by key.
  return a.key > b.key ? 1 : b.key < a.key ? -1 : 0; 
});

// tips is now:
// [{key:"tip_4", value:10}, {key:"tip_1", value:4}, {key:"tip_2", value:2}, {key:"tip_3", value:2}]

// loop over the tips
for (var tip, i=0; tip = tips[i]; i++) {
  console.log(tip.key+": "+tip.value);
}

// Outputs:
// tip_4: 10
// tip_1: 4
// tip_3: 2
// tip_2: 1

1 Comment

you would have to do parse the key and do a numeric comparison since by default the comparisons will be in lexicographic order and things like "tip_10" < "tip_8" will return true.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.