Using http://fusejs.io/
In just about all situations, I'm finding that the 'indices returned contain pretty much the entire string.
For a very simple example, if you go to fusejs.io, and change the first object (in 'step 1' on the left) to
{
title: "so ummmmmm Old Man's War is a book about a thing",
author: {
firstName: "John",
lastName: "Scalzi"
}
},
then tick 'Include matches' (in 'step 2' in the middle)
the resulting indices matches most of the strong, including parts that are obviously way off:
"matches": [
{
"indices": [
[
0,
0
],
[
2,
2
],
[
4,
10
],
[
14,
23
]
],
"value": "so ummmmmm Old Man's War is a book about a thing",
"key": "title",
"arrayIndex": 0
}
]
whereas I'm expecting it to just return the matched part of the string, like so:
"matches": [
{
"indices": [
[
14,
23
]
],
"value": "Man's War",
"key": "title",
"arrayIndex": 0
}
]
I've tried it in my own app and seeing similar results across a large dataset. The matching itself is quite accurate - it's just the highlighting via matches[i].indices that's wrong. It seems to always match up to the matched string, and also sometimes far beyond. Am I going bonkers? Or is this just not possible with fuse.js?
Thanks!
P.S. Can someone please let me know if I'm supposed to include or not include the 'javascript' tag on a library question like this?
Related
JSON Object:
{
"students_detail": [
{
"student_id": 1,
"name": "abc",
"roll_number": 10
},
{
"student_id": 2,
"name": "pqr",
"roll_number": 12
}
],
"subject_details": [
{
"subject_id": 1,
"subject_name": "math"
},
{
"subject_id": 2,
"subject_name": "english"
}
],
"exam_details": [
{
"exam_id": 1,
"exam_name": "Prelim"
}
],
"mark_details": [
{
"id": 1,
"exam_id": 1,
"subject_id": 1,
"student_id": 1,
"mark": 51
},
{
"id": 2,
"exam_id": 1,
"subject_id": 2,
"student_id": 2,
"mark": 61
}
]
}
Ouptut:
{
"student_mark_details": [
{
"abc": {
"roll_number": 10,
"Prelim": [
{
"subject_name": "math",
"mark": 51
}
]
},
"pqr": {
"roll_number": 12,
"Prelim": [
{
"subject_name": "english",
"mark": 61
}
]
}
}
]
}
i tried using loops and accesing student_id in both object and comparing them but code gets too messy and complex,is there any way i can use map() or filter() in this or any other method.
i have no idea where to start,my brain is fried i know im asking lot but help will be appreciated (any link/source where i can learn this is fine too)
Your output object really has a weird format: student_mark_details is an array of size 1 that contains an object that has all your students in it. Anyway, this should give you what you need. It is a format that you find often because it is a system with primary key and secondary key used a lot in databases.
The key to manage that is to start with what is at the core of what you are looking for (here, you want to describe students, so you should start from there), and then navigate the informations you need by using the primary/secondary keys. In JS, you can use the find() function in the case where one secondary key can be linked only to one primary key (ex: one mark is linked to one exam), and the filter() function when a secondary key can be linked to multiple secondary keys (ex: a student is linked to many grades).
I am not sure if this is 100% what you need because there are maybe some rules that are not shown in your example, but it solves the problem you submitted here. You might have to test it and change it depending of those rules. I don't know what your level is so I commented a lot
const data = {
"students_detail": [
{
"student_id": 1,
"name": "abc",
"roll_number": 10
},
{
"student_id": 2,
"name": "pqr",
"roll_number": 12
}
],
"subject_details": [
{
"subject_id": 1,
"subject_name": "math"
},
{
"subject_id": 2,
"subject_name": "english"
}
],
"exam_details": [
{
"exam_id": 1,
"exam_name": "Prelim"
}
],
"mark_details": [
{
"id": 1,
"exam_id": 1,
"subject_id": 1,
"student_id": 1,
"mark": 51
},
{
"id": 2,
"exam_id": 1,
"subject_id": 2,
"student_id": 2,
"mark": 61
}
]
}
function format(data) {
const output = {
"student_mark_details": [{}]
};
//I start by looping over the students_detail because in the output we want a sumary by student
data.students_detail.forEach(student => {
//Initialization of an object for a particular student
const individualStudentOutput = {}
const studentId = student.student_id;
const studentName = student.name;
//The rollNumber is easy to get
individualStudentOutput.roll_number = student.roll_number;
//We then want to find the exams that are linked to our student. We do not have that link directly, but we know that our student is linked to some marks
//Finds all the marks that correspond to the student
const studentMarkDetails = data.mark_details.filter(mark => mark.id === studentId);
studentMarkDetails.forEach(individualMark => {
//Finds the exam that corresponds to our mark
const examDetail = data.exam_details.find(exam => individualMark.exam_id === exam.exam_id);
//Finds the subject that corresponds to our mark
const subjectDetail = data.subject_details.find(subject => individualMark.subject_id === subject.subject_id);
//We then create a grade that we will add to our exam
const grade = {
subject_name: subjectDetail.subject_name,
mark: individualMark.mark
}
//We then want to add our grade to our exam, but we don't know if our output has already have an array to represent our exam
//So in the case where it does not exist, we create one
if (!individualStudentOutput[examDetail.exam_name]) {
individualStudentOutput[examDetail.exam_name] = [];
}
//We then add our grade to the exam
individualStudentOutput[examDetail.exam_name].push(grade);
});
//Now that we have finished our individual output for a student, we add it to our object
output.student_mark_details[0][studentName] = individualStudentOutput;
})
return output;
}
console.log(JSON.stringify(format(data)))
Using selenium, I took memory snapshot of a website with driver.execute_script(":takeHeapSnapshot") and extracted its metadata:
{
"snapshot": {
"meta": {
"node_fields": [
"type", "name", "id", "self_size", "edge_count", "trace_node_id", "detachedness"
],
"node_types": [
["hidden", "array", "string", "object", "code", "closure", "regexp", "number", "native", "synthetic", "concatenated string", "sliced string", "symbol", "bigint"],
"string", "number", "number", "number", "number", "number"
],
"edge_fields": [
"type", "name_or_index", "to_node"
],
"edge_types": [
["context", "element", "property", "internal", "hidden", "shortcut", "weak"],
"string_or_number", "node"
],
"trace_function_info_fields": [
"function_id", "name", "script_name", "script_id", "line", "column"
],
"trace_node_fields": [
"id", "function_info_index", "count", "size", "children"
],
"sample_fields": [
"timestamp_us", "last_assigned_id"
],
"location_fields": [
"object_index", "script_id", "line", "column"
]
},
"node_count": 6182075,
"edge_count": 17793245,
"trace_function_count": 0
}
}
Can someone explain, please, what each field means and how to use that information to extract data? What are nodes, edges, location fields etc. As example, let's say, I have an ArrayBuffer on heap the size of which I know (and it's unique) and I want to retrieve this array. Is it possible to do with the snapshot?
meta fields group explains the content of the different arrays of the snapshot.
The snapshot has the nodes array. This array has 7 numbers for every node in the heap and node_fields array describes the meaning for all of these 7 numbers.
at the same time node_types array describes the types for these 7 numbers.
For example if you have the next 7 numbers in the nodes array
[
.....,
2, 9, 13, 42, 0, 0, 0,
......
then the Nth node in the heap
has "type" string, because node_types[0][2] == 'string',
has "name" which is hidden in the strings array of the heap. i.e. strings[9],
has "id" 13,
uses 42 bytes of the heap
has 0 references to the other objects in the heap
has "trace_node_id" = 0,
has "detachness" = 0,
The edges array has a triplet of numbers for the every edge and you could see the names of every number in the edges_fields and the types in the edge_types array.
For example the triplet 2, 17, 79 in the edges array at the offset 0 means:
the edge is actually a property of an object because edge_types[0][2] = 'property'
the name of the property is hidden in the strings array with index 17
and it points to the node with id 79. (actually I forgot, it is the index of the node or the id of the node)
if the first node of the nodes array has the edge_count = 2, then the first 2 triplets of the edges array are the edges from this node to some other nodes, etc.
I hope this explanation could give you some light how to understand the content of the heap snapshot.
so I have a JSON array that looks like this:
[
{
row: [
{
boat: {
description: 'Books',
version: '2',
id: 6
},
airplanes: [
{
airplane: [
{
description: 'DVD',
version: 2,
uid: 69,
wid: 65,
id: 84
}
],
trains: {
train: [
{
description: 'Pictures',
version: 2,
id: 149
}
],
actions: [
{
description: 'This is a really long sentence.',
version: 2,
tid: 69.01,
id: 452
},
{
description: 'article 2',
version: 2,
tid: 69.02,
id: 453
},
{
description: 'developer 1',
version: 2,
tid: 69.03,
id: 454
}
]
}
},
{
airplane: [
{
description: 'Games',
version: 2,
uid: 65,
wid: 61,
id: 80
}
],
trains: {
train: [
{
description: 'another great descriptions.',
version: 2,
id: 145
}
],
actions: [
{
description: 'being indecisive is good.',
version: 2,
tid: 65.01,
id: 442
},
{
description: 'couches are comfortable',
version: 2,
tid: 65.02,
id: 443
}
]
}
}
]
}
]
}
]
I am trying to sort the above output by 'wid' in ascending order but still be able to preserve the overall order. For example in the above the wid in element 0 of the array is 65, and element 1 of the array the wid value is 61. Therefore, element 1 and element 0 should be swapped. Is there any built in javascript method to sort json like this?
I will have a json array output a lot larger than the provided example.
Both Underscore and LoDash have a sort method that will do what you're looking for. In this example I am assuming that you have the data structure you showed stored in a variable called data.
_.each(data, function(obj) {
_.each(obj.row, function(row) {
// note the reassignment, _.sortBy does not sort in-place
row.airplanes = _.sortBy(row.airplanes, function(airplane) {
return airplane.wid; // This will sort ascending.
// To sort descending, simply multiply by -1
});
});
});
So what is this doing? It's taking each array element in your root data structure and looping over it (that's the first _.each). Then in each of those objects, it is looping over each row element and sorting row.airplanes array by the wid element contained in each.
Hopefully this helps you. As an aside, that data you posted is strictly invalid JSON. Each key should be double quoted, i.e., "row", instead of just row and single quotes are invalid for delimiting strings, i.e., "DVD" instead of 'DVD'. Also, your boat version is a string whereas your other version identifiers are integers, it's a good idea to try and keep your version identifiers as integers.
I recommend using the excellent jq commandline JSON processor. Extremely fast since it was written in portable C. Easy to understand documentation.
cat <file.json> | jq . -S
I have a collection that looks like the ff:
{
"word":"approve",
"related" : [
{
"relationshipType" : "cross-reference",
"words" : [
"note"
]
},
{
"relationshipType" : "synonym",
"words" : [
"demonstrate",
"ratify",
]
}
],
},
{
"word": "note",
"related" : [
{
"relationshipType" : "synonym",
"words" : [
"butt",
"need",
],
},
{
"relationshipType" : "hypernym",
"words" : [
"air",
"tone",
]
},
{
"relationshipType" : "cross-reference",
"words" : [
"sign",
"letter",
"distinction",
"notice",
]
},
],
}
I want to group/categorize all the objects which have a word in another object, be it
the name (as the cross-reference field of 'approve', has note. searches for the word 'note'.
or
the word is in another object's related words. like having a synonym of 'ratify' under 'approve' then looking for other objects that have have 'ratify' in any field of their related words.
Then save these to a new collection called categories.
result should Be:
{
"category": 1,
"words":["approve","note"],
}
...and the value of the word field for all the linked objects in the words array.
Any way how to do this.. i'm thinking about some sort of recursion in checking links but i'm not sure how to implement. another potential problem is going back to the parent layer creating an infinite loop of sorts.
and is it possible through map reduce?
EDIT: clarity.
Im new to JSON and I have to deal with a complex one.
Please see image below:
It has an error:
I don't know how to properly separate the 2 json arrays. I even tried to use : instead of , on line 18 but I still get errors. BTW, I use http://jsonlint.com/ to validate.
On line 2 you gave a key, but failed to do so on line 19. You have to keep the structure.
Remove the key on line 2, they shouldn't be used for arrays in that way.
Edit: In addition, you are trying to put arrays right in objects, switch the opening and ending object marks ({}) with ([]) for arrays on your first and last line.
[
[
{...},
{...},
...
{...}
],
[
{...},
{...},
...
{...}
],
...
[
{...},
{...},
...
{...}
]
]
I believe the correct way to build this JSON should be:
{
"glEntries": [
{
"generalLedgerId":1,
"accountId": 34,
"amount" : 32334.23,
"descripction": "desc1",
"debit" : "Yes"
},
{
"generalLedgerId":2,
"accountId": 35,
"amount" : 323.23,
"descripction": "desc",
"debit" : "Yes"
},
...
]
}
There are many ways to construct JSON data, but it depends on your data and the way you want to present it. Here are a couple examples - hope it helps:
{
"glEntries": [
{
"object1-prop1": "one"
},
{
"object2-prop1": 1,
"object2-prop2": "two"
},
{
"object3-prop1": [
"a",
"r",
"r",
"a",
"y"
],
"object3-prop1.1": "string"
}
],
"otherEntries": [
{
"objectx": "x"
},
{
"objecty": "y"
},
{
"objectz": [
1,
2,
3,
4
]
}
],
"oneEntry": "json"
}
Other Example:
[
{
"obj1-prop": 222
},
{
"obj2-prop": "object2"
},
{
"obj3-prop": "Object3"
},
[
"a",
"r",
"r",
"a",
"y",
777,
888
],
"string",
178,
{
"objectProp": "testing123"
}
]
You have more {} than needed and will make parsing your JSON more difficult:
Structure will work a lot better like this:
{"glentries":[
{ "property1":"value", "property2" : "value",..... "lastProperty": "value"},
{ "property1":"value", "property2" : "value",..... "lastProperty": "value"},
{ "property1":"value", "property2" : "value",..... "lastProperty": "value"}
]
}
Now glentries is an array of objects that have multiple properties to them.
alert( glentries[0].property2 )
The parent structure is an Object, so it is expecting a string Key for the second array. It it's supposed to be an array of arrays, you should be using an array and not an Object.