3

I would like to perform a fuzzy search on an Object with a flat hierarchy. On the demo page of Fuse.js you have to specify a key / keys to look for in the Object. Unfortunately I do not have a specific identifier.

Fuse.js Demo:

var books = [{
  title: "Old Man's War",
  author: {
    firstName: "John",
    lastName: "Scalzi"
  }
}];
var fuse = new Fuse(books, { keys: ["title", "author.firstName"] });

My Setup:

const data = {
  "100": "https://assets-cdn.github.com/images/icons/emoji/unicode/1f4af.png?v6",
  "1234": "https://assets-cdn.github.com/images/icons/emoji/unicode/1f522.png?v6",
  "+1": "https://assets-cdn.github.com/images/icons/emoji/unicode/1f44d.png?v6",
  "-1": "https://assets-cdn.github.com/images/icons/emoji/unicode/1f44e.png?v6"
};

const fuse = new Fuse(data, { keys: ??? });
fuse.search('+1'); // should return "https://assets-cdn.github.com/images/icons/emoji/unicode/1f44d.png?v6",
I wrestled a bear once.
  • 22,983
  • 19
  • 69
  • 116
marcobiedermann
  • 4,317
  • 3
  • 24
  • 37

2 Answers2

6

You could get the keys for your dynamic object using the Object.keys() function. If you wish to support older browsers too you can find a polyfill implementation here (under Polyfill).

Then, you could supply Fuse, the keys like this: Object.keys(myobject).

EDIT:

In order to transform the object itself you could do something similar to what Jordan has suggested:

var newData = Object.keys(data).map(function(key) {
  return { id: key, link: data[key]};
}) 

And then the keys array is ['id'] and you should search by the id.

Gershon Papi
  • 5,008
  • 3
  • 24
  • 50
  • Thank you Gershon, this work. I get all keys of my Object. Unfortunately I have to use in Array instead of an Object. The GitHub API only returns an JSON Object. – marcobiedermann Nov 15 '16 at 22:01
  • @marcobiedermann using the example you've given `Object.keys(data)` should return `[100, 1234, +1, - 1]`. Isn't that what you need? – Gershon Papi Nov 15 '16 at 22:05
  • Yes, your comment is right. But as I mentioned, Fuse.js requires an Array to search on. GitHub just returns an Object. – marcobiedermann Nov 15 '16 at 22:06
5

First parse your data:

const data = JSON.parse(json);

Then one way to do it (but for sure it would be slower than second suggestions, because of all of the keys are included in the search):

const fuse = new Fuse(data, { keys: data.keys() });

Or you can change your data structure dynamically:

let structuredData = [];

for (key in data)
    structuredData.push({
        "id": key,
        "url": structuredData[key]
    });

const fuse = new Fuse(structuredData, { keys: ["id"] });
Jordan Enev
  • 16,904
  • 3
  • 42
  • 67
  • Thank you for your answer. Unfortunately I do not have an Array to look for. The response from the GitHub API is an JSON Object – marcobiedermann Nov 15 '16 at 22:00
  • No problem. Once data is received, first change its structure. I'll update my answer. – Jordan Enev Nov 15 '16 at 22:02
  • Thank you so much. I just figured this out by myself the second you posted your answer. JSON.parse(data) won't work because this requires the object to be inside a String ("{ "key": "value", "key": "value"}") – marcobiedermann Nov 15 '16 at 22:25
  • If the response from GitHub is a String with JSON structure then first parse it. If in your success callback you receive directly JSON object, then skip the parsing step. – Jordan Enev Nov 15 '16 at 22:33