What Is the Fastest Way to Sort a Hash

How to sort a hash by value in descending order and output a hash in ruby?

Try:

Hash[h.sort.reverse]

This should return what you want.

Edit:

To do it by value:

Hash[h.sort_by{|k, v| v}.reverse]

Fastest way to arrange sort and print large HashMap?

A min priority heap data structure would be handy in this case. You can just add elements to it in one go and every time the size crosses 10 remove the top element (min element).

Here is a basic implementation for the data structure HashMap:

import java.util.*;

public class Test
{
public static void main(String[] args)
{
PriorityQueue<Map.Entry<String,Double>> queue = new PriorityQueue<>(10, new Comparator<Map.Entry<String, Double>>() {
@Override
public int compare(Map.Entry<String,Double> x, Map.Entry<String,Double> y)
{
if (x.getValue() < y.getValue())
{
return -1;
}
if (x.getValue() > y.getValue())
{
return 1;
}
return 0;
}
});

HashMap<String,Double> balances = new HashMap<String,Double>();
balances = Test.populateBalances(); // return the populated map

for (Map.Entry<String, Double> entry : balances.entrySet()) {
queue.add(entry);
if (queue.size() > 10)
queue.poll();
}

for (Map.Entry<String, Double> entry : queue)
System.out.println(entry.getKey() + ":" + entry.getValue());
}

public static HashMap<String, Double> populateBalances() {
HashMap<String,Double> balances = new HashMap<String,Double>();
balances.put("test1", 1000.2);
balances.put("test2", 200.3);
balances.put("test3", 12000.2);
balances.put("test4", 2050.3);
balances.put("test5", 1034.2);
balances.put("test6", 210.3);
balances.put("test7", 10.2);
balances.put("test8", 0.3);
balances.put("test9", 13210.2);
balances.put("test10", 2223.3);
balances.put("test11", 101.2);
balances.put("test12", 200.1);

return balances;
}

}

What is the most efficient way to sort hashes in ruby?

Assuming that powerrankings is not as you showed but is rather,

powerrankings = {
"green" => {:price=>24.88, :numreviews=>822, :avgStarsRank=>41.0, :reviewsrank=>28, :powerrank=>73.976},
"steve" => {:price=>14.96, :numreviews=>3, :avgStarsRank=>40.0, :reviewsrank=>0, :powerrank=>42.992000000000004},
"joey" => {:price=>40.27, :numreviews=>814, :avgStarsRank=>44.0, :reviewsrank=>28, :powerrank=>80.054},
"board" => {:price=>14.96, :numreviews=>3, :avgStarsRank=>40.0, :reviewsrank=>0, :powerrank=>47},
"john" => {:price=>40.27, :numreviews=>814, :avgStarsRank=>44.0, :reviewsrank=>28, :powerrank=>16}
}

then,

powerrankings.sort_by{|_, h| h[:powerrank]}.reverse.first(3).map(&:first)
# => ["joey", "green", "board"]

How to sort a Ruby Hash alphabetically by keys

Assuming you want the output to be a hash which will iterate through keys in sorted order, then you are nearly there. Hash#sort_by returns an Array of Arrays, and the inner arrays are all two elements.

Ruby's Hash has a constructor that can consume this output.

Try this:

temp = Hash[ temp.sort_by { |key, val| key } ]

or more concisely

temp = temp.sort_by { |key| key }.to_h

If your hash has mixed key types, this will not work (Ruby will not automatically sort between Strings and Symbols for instance) and you will get an error message like comparison of Symbol with String failed (ArgumentError). If so, you could alter the above to

temp = Hash[ temp.sort_by { |key, val| key.to_s } ] 

to work around the issue. However be warned that the keys will still retain their original types which could cause problems with assumptions in later code. Also, most built-in classes support a .to_s method, so you may get unwanted results from that (such as unexpected sort order for numeric keys, or other unexpected types).

You could, in addition, convert the keys to Strings with something like this:

temp = Hash[ temp.map { |key, val| [key.to_s, val] }.sort ] 

. . . although this approach would lose information about the type of the original key making it impossible to refer back to the original data reliably.

What is the best method to sort a Hashtable who has a class as value with multiple variables (Integers) in Java?

EDIT: Edited the post to sort the whole entrySet() instead.

To get a custom sort order you would define a Comparator<Map.Entry<String, Values>>, specifying the order in what you would like to compare the entries from your map, and if any part of the sort should be done in reverse (descending).

From your description I think you wanted a to be the first to be sorted descending and then b to be sorted descending as well.

Comparator<Map.Entry<String, Values>> myValuesComparator = Comparator
.comparingInt((Map.Entry<String, Values> entry) -> entry.getValue().a)
.thenComparingInt(entry -> entry.getValue().b)
.reversed();

Then you turn your hash.entrySet() into a stream by calling .stream() and then you sort the stream of entries with your comparator by calling .sorted(myValuesComparator). In the end you collect the sorted entries into a new collection, we will collect them into a List<Map.Entry<String, Values>> here.

List<Map.Entry<String, Values>> list = hash.entrySet()
.stream()
.sorted(myValuesComparator)
.collect(Collectors.toList());

If you want to check the result you can place a breakpoint and check the elements inside the list or just print the whole list

for (Map.Entry<String, Values> entry : list) {
System.out.printf("Key: %s, score: %d, time of last update: %d%n", entry.getKey(), entry.getValue().a, entry.getValue().b);
}

This same code also works if you change your Hashtable to a HashMap, as suggested by Mark Rotteveel in the comments, since Hashtable is considered an outdated class.

Here is my sample output

Key: Test9, score: 11, time of last update: 3
Key: Test8, score: 11, time of last update: 2
Key: Test7, score: 11, time of last update: 1
Key: Test6, score: 10, time of last update: 3
Key: Test5, score: 10, time of last update: 2
Key: Test4, score: 10, time of last update: 1
Key: Test3, score: 1, time of last update: 3
Key: Test2, score: 1, time of last update: 2
Key: Test1, score: 1, time of last update: 1

for input

hash.put("Test1", new Values( 1, 1));
hash.put("Test2", new Values( 1, 2));
hash.put("Test3", new Values( 1, 3));
hash.put("Test4", new Values(10, 1));
hash.put("Test5", new Values(10, 2));
hash.put("Test6", new Values(10, 3));
hash.put("Test7", new Values(11, 1));
hash.put("Test8", new Values(11, 2));
hash.put("Test9", new Values(11, 3));

Fastest way to index large sorted hash file

ripgrep, like any other tool that's able to work with unsorted input files at all, is the wrong tool for this job. When you're trying to grep sorted inputs, you want something that can bisect your input file to find a position in logarithmic time. For big enough inputs, even a slow O(log n) implementation will be faster than a highly optimized O(n) one.

pts-line-bisect is one such tool, though of course you're also welcome to write your own. You'll need to write it in a language with full access to the seek() syscall, which is not exposed in bash.

Which is faster to find an item in a hashtable or in a sorted list?

Algorithm complexity is a good thing to know, and hashtables are known to be O(1) while a sorted vector (in your case I guess it is better to use a sorted array than a list) will provide O(log n) access time.

But you should know that complexity notation gives you the access time for N going to the infinite. That means that if you know that your data will keep growing, complexity notation gives you some hint on the algorithm to chose.

When you know that your data will keep a rather low length: for instance having only a few entries in your array/hashtable, you must go with your watch and measure. So have a test.

For instance, in another problem: sorting an array. For a few entries bubble sort while O(N^2) may be quicker than .. the quick sort, while it is O(n log n).

Also, accordingly to other answers, and depending on your item, you must try to find the best hash function for your hashtable instance. Otherwise it may lead to dramatic bad performance for lookup in your hashtable (as pointed out in Hank Gay's answer).

Edit: Have a look to this article to understand the meaning of Big O notation .



Related Topics



Leave a reply



Submit