1

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.

kenricf
  • 13
  • 3

3 Answers3

1

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.

Stephen S
  • 294
  • 5
  • 20
  • Downvoted because an element is not guaranteed to serialize in the same order. That is, there is no guarantee of property order in JS objects in different engines, and sometimes even within the same engine depending on how the object was populated. See https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – Juan Mendes Aug 18 '17 at 22:03
  • @JuanMendes oh, you are correct, I had forgotten about that. Hm. – Stephen S Aug 18 '17 at 22:05
  • What you could do is serialize the JSON making sure the property names are in alphabetical order (you couldn't just use `JSON.stringify`) – Juan Mendes Aug 18 '17 at 22:07
0

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];
    });
});
Nina Scholz
  • 323,592
  • 20
  • 270
  • 324
0

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:)

Ali Adlavaran
  • 3,433
  • 2
  • 21
  • 43