kenricf
kenricf

Reputation: 13

Reduce javascript object to unique identifier

I have an object that I'm storing page settings in that looks something like this:

var filters={
    "brands":["brand1","brand2","brand3"],
    "family":"reds",
    "palettes":["palette1","palette2","palette3"],
    "color":"a1b2"
};

This object is constantly being changed as the user browses the page. I looking for some fast way in the code (maybe using a built in jquery or javascript function) to reduce the current settings object to a unique identifier I can reference without using a lot of loops. Maybe something like this:

"brandsbrand1brand2brand3familyredspalettespalette1palette2palette3colora1b2"

Doesn't have to necessarily convert the object to a long string like that, as long as it is something that will be unique to a particular group of settings. And I won't need to convert this identifier back into the object later.

EDITS: I need to give some more information.

I'm looking to store the items of the results of the filters I'm doing inside a variable that's named the same as the unique ID. So, var uniqueID1 is from the settings object that has brand1 and brand2, and contains ["filteredObject1_1","filteredObject1_2"...,"filteredObject1_500"], and var uniqueID2 is from the settings object that has brand3 and brand4, and contains ["filteredObject2_1","filteredObject2_2"...,"filteredObject2_500"]. What I'm looking to do is avoid doing really really slow filtering code more than once on a bunch of items by storing results of the filtering in unique variables.

So:

  1. Convert settings to unique id and see if that if that variable exists.
  2. If variable exists, just get that variable that has the already filtered items.
  3. If variable doesn't exist, do the really slow filtering on hundreds of items and store these items in unique id variable.

Hopefully I just didn't make this more confusing. I feel like I probably made it more confusing.

Upvotes: 1

Views: 1557

Answers (3)

Stephen S
Stephen S

Reputation: 374

You can use JSON, which is a method of stringifying objects that was designed for JavaScript.

var filters={
    "brands":["brand1","brand2","brand3"],
    "family":"reds",
    "palettes":["palette1","palette2","palette3"],
    "color":"a1b2"
};

var uniqueId = JSON.stringify(filters);

uniqueId equals the following string:

{"brands":["brand1","brand2","brand3"],"family":"reds","palettes":["palette1","palette2","palette3"],"color":"a1b2"}

This has the added benefit of being able to be turned back into an object with JSON.parse(uniqueId).

Note that with JSON.stringify, two objects with have exactly the same values will be converted into the same unique id.

EDIT:

Please let me know if I interpreted your edit correctly. However, I think this is what you want to do.

//object that will act as a cache
var cached_filters = {}

//this assumes the existence of a get_filter function that processes the filters object

function get_cached_filter(filters) {
    let uniqueId = JSON.stringify(filters);

    //use already cached filters
    if (cached_filters[uniqueId]) {
        return cached_filters[uniqueId];

    //create filter and cache it
    } else {
        cached_filters[uniqueId] = get_filter(filters);
        return cached_filters[uniqueId];
    }
}

This will store an object that has keys for each filter each time you call get_cached_filter. If get_cached_filter has already been called with the same exact filter, it will use it from the cache instead of recreating it; otherwise, it will create it and save it in the cache.

Upvotes: 1

Ali Adlavaran
Ali Adlavaran

Reputation: 3735

If you won't need to convert this identifier back into the object later, Here you can use this simple hashing function:

function UniqueHashCode(obj){
    var str = JSON.stringify(obj) 
    var hash = 0;
    if (str.length == 0) return hash;
    for (i = 0; i < str.length; i++) {
        char = str.charCodeAt(i);
        hash = ((hash<<5)-hash)+char;
        hash = hash & hash; // Convert to 32bit integer
    }
    return hash;
}

function UniqueHashCode(obj){
    var str = JSON.stringify(obj) 
    var hash = 0;
    if (str.length == 0) return hash;
    for (i = 0; i < str.length; i++) {
        char = str.charCodeAt(i);
        hash = ((hash<<5)-hash)+char;
        hash = hash & hash; // Convert to 32bit integer
    }
    return hash;
}
var filters={
    "brands":["brand1","brand2","brand3"],
    "family":"reds",
    "palettes":["palette1","palette2","palette3"],
    "color":"a1b2"
};
alert(UniqueHashCode(filters));

This function create a simple and very short integer (for example 661801383) by given object.

I hope to be helpful for you:)

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386624

You could iterate the filter object and filter with Array#filter the data.

data.filter(function (o) {
    return Object.keys(filters).every(function (k) {
        return Array.isArray(filters[k]) 
            ? filters[k].some(function (f) { return o[k] === f; })
            : o[k] === filters[k];
    });
});

Upvotes: 0

Related Questions