How implement javascript Map structure with dynamic data ? - javascript

I am trying to create tree like component,
for the first level data is coming from the server ,
if the user clicks the node i need to populate the child nodes with the data from service call.
what is the best way to save the data for this tree component ?
because user will do some operations on the tree component like remove, add & move. Finally i need to send the updated data to the server .

This is the hashmap functionality I use in javascript.
I based it off the docs of java 7 hashmap.
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
I added the load and save variables to allow JSON storage. be careful though. if you stored any complex objects(like a hashmap in a hashmap) you will lose that.
You'd have to implement your own object instantiatiors in the load and save function.
A JSfiddle to play with if you like:
http://jsfiddle.net/mdibbets/s51tubm4/
function HashMap() {
this.map = {};
this.listsize = 0;
}
HashMap.prototype._string = function(key) {
if(typeof key.toString !== 'undefined') {
return key.toString();
}
else {
throw new Error('No valid key supplied. Only supply Objects witha toString() method as keys');
}
}
HashMap.prototype.put = function(key,value) {
key = this._string(key);
if(typeof this.map[key] === 'undefined') {
this.listsize++;
}
this.map[key] = value;
}
HashMap.prototype.get = function(key) {
key = this._string(key);
return this.map[key];
}
HashMap.prototype.containsKey = function(key) {
key = this._string(key);
return !(this.map[key] === 'undefined');
}
HashMap.prototype.putAll = function(hashmap) {
if(hashmap instanceof HashMap) {
var othermap = hashmap.map;
for(var key in othermap) {
if(othermap.hasOwnProperty(key)) {
if(typeof this.map[key] === 'undefined') {
this.listsize++;
}
this.map[key] = othermap[key];
}
}
}
else {
throw new Error('No HashMap instance supplied');
}
}
HashMap.prototype.remove = function(key) {
key = this._string(key);
var ret = null;
if(typeof this.map[key] !== 'undefined') {
ret = this.map[key];
delete this.map[key];
this.listsize--;
}
return ret;
}
HashMap.prototype.clear = function() {
this.map = {};
this.listsize = 0;
}
HashMap.prototype.containsValue = function(value) {
for(var key in this.map) {
if(this.map.hasOwnProperty(key)) {
if(this.map[key] === value) {
return true;
}
}
}
return false;
}
HashMap.prototype.clone = function() {
var ret = new HashMap();
ret.map = this.map;
ret.listsize = this.listsize;
return ret;
}
HashMap.prototype.entrySet = function() {
return this.map;
}
HashMap.prototype.keySet = function() {
var ret = [];
for(var key in this.map) {
if(this.map.hasOwnProperty(key)) {
ret.push(key);
}
}
return ret;
}
HashMap.prototype.values = function() {
var ret = [];
for(var key in this.map) {
if(this.map.hasOwnProperty(key)) {
ret.push(this.map[key]);
}
}
return ret;
}
HashMap.prototype.size = function(activeCheck) {
//Active check is expensive.
if(typeof activeCheck !== 'undefined' && activeCheck) {
var count = 0;
for(var key in this.map) {
if(this.map.hasOwnProperty(key)) {
count++;
}
}
return count;
}
return this.listsize;
}
HashMap.prototype.save = function(){
return JSON.stringify(this.map);
}
HashMap.prototype.load = function(json) {
if(typeof json !== 'string') {
throw new Error("No valid input supplied. Only supply JSON Strings");
}
this.map = JSON.parse(json);
this.listsize = this.size(true);
}
var map = new HashMap();
console.log(
map.put('hello', true),
map.get('hello'),
map.put('hello',10),
map.put('world',20),
map.values(),
map.keySet(),
map.entrySet(),
map.containsValue('twoshoes'),
map.size()
);
var map2 = new HashMap();
map2.put('goody','twoshoes');
map2.putAll(map);
console.log(
map2.get('hello'),
map2.values(),
map2.keySet(),
map2.entrySet(),
map2.containsValue('twoshoes'),
map2.size()
);
var map3 = new HashMap();
map3.load(map2.save());
console.log(
map3.get('hello'),
map3.values(),
map3.keySet(),
map3.entrySet(),
map3.containsValue('twoshoes'),
map3.size()
);

Related

Grouping by fields after reduce is not working in JavaScript

There is a complex object and based on an array which is given as an input I need to modify its properties. Illustration is shown below. If the "field" is same , add them to "or" array .If its different "field" add them to "and" array along with its "value". I am using Set to get keys from both source and input and using them to group based on its keys. Also whenever there are duplicates .ie., suppose the "filterObj" already has the same (field, value) pair. Be it in "and" or inside "or",Then don't add it in the final object
Sandbox: https://codesandbox.io/s/optimistic-mirzakhani-pogpw-so-dpvis
There is a TestCases file in the sandbox which its needs to pass
let filterObj = {
feature: "test",
filter: {
and: [{ field: "field2" }]
}
};
let obj = [{ field: "field2", value: "3" }];
let all_filters = [];
if (filterObj.filter.and && filterObj.filter.and.hasOwnProperty("or")) {
all_filters = [...filterObj.filter.and.or];
} else if (filterObj.filter.and) {
all_filters = [...filterObj.filter.and];
}
const all_objs = [...obj, ...all_filters];
const uniqKeys = all_objs.reduce(
(acc, curr) => [...new Set([...acc, curr.field])],
[]
);
const updateItems = uniqKeys.map(obj => {
const filter_items = all_objs.filter(item => item.field === obj);
let resultObj = {};
if (filter_items && filter_items.length > 1) {
resultObj.or = [...filter_items];
} else if (filter_items && filter_items.length === 1) {
resultObj = { ...filter_items[0] };
}
return resultObj;
});
var result = { ...filterObj, filter: { and: [...updateItems] } };
console.log(result);
Try it.
I redid the implementation, it happened more universally.
Parses any filters according to your algorithm that it finds.
All test cases are worked.
Sandbox link: https://codesandbox.io/s/optimistic-mirzakhani-pogpw-so-i1u6h
let filterObj = {
feature: "test",
filter: {
and: [
{
field: "field1",
value: "2"
}
]
}
};
let obj = [
{
field: "field1",
value: "2"
},
{
field: "field1",
value: "1"
}
];
var FilterController = function(filter) {
var self = this;
self.filter = filter;
// encapsulated map of objects by fields
var storeMap = {};
// counter of objects
var counter = 0;
var tryPutObjectToMap = function(object) {
if (typeof object === "object") {
// get type for grouping
var objectType = self.getObjectGroupType(object);
if (objectType !== null) {
// cheack have group
if (!storeMap.hasOwnProperty(objectType)) {
storeMap[objectType] = [];
}
var duplicate = storeMap[objectType].find(function(sObject) {
return self.getObjectValue(sObject) === self.getObjectValue(object);
});
// check duplicate
if (duplicate === undefined) {
counter++;
storeMap[objectType].push(object);
} else {
// TODO: Handle duplicates
}
} else {
// TODO: handle incorrect object
}
}
};
// get filter structure from map
var getFilterStructureFromMap = function() {
var result = {};
// check exists root filter and filed if have objects
if (counter > 0) {
result["and"] = [];
}
for (var key in storeMap) {
if (storeMap.hasOwnProperty(key)) {
var array = storeMap[key];
if (array.length > 1) {
result["and"].push({
// clone array
or: array.slice()
});
} else {
result["and"].push(array[0]);
}
}
}
return result;
};
// rewrite and get current filter
// if you need^ create new object for result
self.rewriteAndGetFilter = function() {
self.filter.filter = getFilterStructureFromMap();
return self.filter;
};
// not prototype function for have access to storeMap
self.putObjects = function(objects) {
if (Array.isArray(objects)) {
// recursive push array elements
objects.forEach(element => self.putObjects(element));
// handle array
} else if (typeof objects === "object") {
// handle object
if (objects.hasOwnProperty("and") || objects.hasOwnProperty("or")) {
for (var key in objects) {
//no matter `or` or `and` the same grouping by field
// inner object field
if (objects.hasOwnProperty(key)) {
self.putObjects(objects[key]);
}
}
} else {
// filters props not found, try push to store map
tryPutObjectToMap(objects);
}
} else {
// TODO: Handle errors
}
};
if (self.filter.hasOwnProperty("filter")) {
// put and parse current objects from filter
self.putObjects(self.filter.filter);
}
};
// function for grouping objects.
// for you get filed name from object.
// change if need other ways to compare objects.
FilterController.prototype.getObjectGroupType = function(obj) {
if (typeof obj === "object" && obj.hasOwnProperty("field")) {
return obj.field;
}
return null;
};
// get object value
FilterController.prototype.getObjectValue = function(obj) {
if (typeof obj === "object" && obj.hasOwnProperty("value")) {
return obj.value;
}
return null;
};
var ctrl = new FilterController(filterObj);
ctrl.putObjects(obj);
var totalFilter = ctrl.rewriteAndGetFilter();
console.log(totalFilter);
console.log(JSON.stringify(totalFilter));
EDIT 1
I did not change the logic; I made a function based on it.
let filterObj = {
feature: "test",
filter: {
and: [
{
field: "field1",
value: "2"
}
]
}
};
let obj = [
{
field: "field1",
value: 2
},
{
field: "field1",
value: "1"
}
];
function appendToFilter(filter, inputObjects) {
var storeMap = {};
var counter = 0;
var handlingQueue = [];
// if filter isset the appen to handling queue
if (filter.hasOwnProperty("filter")) {
handlingQueue.push(filter.filter);
}
// append other object to queue
handlingQueue.push(inputObjects);
// get first and remove from queue
var currentObject = handlingQueue.shift();
while (currentObject !== undefined) {
if (Array.isArray(currentObject)) {
currentObject.forEach(element => handlingQueue.push(element));
} else if (typeof currentObject === "object") {
if (currentObject.hasOwnProperty("and") || currentObject.hasOwnProperty("or")) {
for (var key in currentObject) {
if (currentObject.hasOwnProperty(key)) {
handlingQueue.push(currentObject[key]);
}
}
} else {
// TODO: append fild exists check
if (currentObject.field) {
if (!storeMap.hasOwnProperty(currentObject.field)) {
storeMap[currentObject.field] = [];
}
var localValue = currentObject.value;
// check duplicate
if (storeMap[currentObject.field].find(object => object.value === localValue) === undefined) {
counter++;
storeMap[currentObject.field].push(currentObject);
}
}
}
}
currentObject = handlingQueue.shift();
}
// create new filter settings
var newFilter = {};
// check exists root filter and filed if have objects
if (counter > 0) { newFilter["and"] = []; }
for (var storeKey in storeMap) {
if (storeMap.hasOwnProperty(storeKey)) {
var array = storeMap[storeKey];
if (array.length > 1) {
newFilter["and"].push({
// clone array
or: array.slice()
});
} else {
newFilter["and"].push(array[0]);
}
}
}
filter.filter = newFilter;
}
// update filterObj
appendToFilter(filterObj, obj);
console.log(filterObj);
EDIT 2,3 (UPDATED)
With others objects support.
export function appendToFilter(filter, inputObjects) {
var storeMap = {};
var others = [];
var counter = 0;
var handlingQueue = [];
// if filter isset the appen to handling queue
if (filter.hasOwnProperty("filter") && filter.filter.hasOwnProperty("and")) {
handlingQueue.push(filter.filter.and);
}
// append other object to queue
handlingQueue.push(inputObjects);
// get first and remove from queue
var currentObject = handlingQueue.shift();
while (currentObject !== undefined) {
if (Array.isArray(currentObject)) {
currentObject.forEach(element => handlingQueue.push(element));
} else if (typeof currentObject === "object") {
if (
currentObject.hasOwnProperty("and") ||
currentObject.hasOwnProperty("or")
) {
for (var key in currentObject) {
if (currentObject.hasOwnProperty(key)) {
handlingQueue.push(currentObject[key]);
}
}
} else {
// TODO: append fild exists check
if (currentObject.field) {
if (!storeMap.hasOwnProperty(currentObject.field)) {
storeMap[currentObject.field] = [];
}
var localValue = currentObject.value;
// check duplicate
if (
storeMap[currentObject.field].find(
object => object.value === localValue
) === undefined
) {
counter++;
storeMap[currentObject.field].push(currentObject);
}
} else {
// handle others objects^ without field "field"
counter++;
others.push(currentObject);
}
}
}
currentObject = handlingQueue.shift();
}
// create new filter settings
var newFilter = {};
// check exists root filter and filed if have objects
if (counter > 0) {
newFilter["and"] = [];
}
for (var storeKey in storeMap) {
if (storeMap.hasOwnProperty(storeKey)) {
var array = storeMap[storeKey];
if (array.length > 1) {
newFilter["and"].push({
// clone array
or: array.slice()
});
} else {
newFilter["and"].push(array[0]);
}
}
}
// Append others to result filter
others.forEach(other => newFilter["and"].push(other));
filter.filter = newFilter;
}

How to convert xml to JSON in suitescript 2.0

I have an XML response that i want to convert it to JSON, i'm currently usingg XPath
var responseNode = xml.XPath.select({
node : xmlDocument,
xpath : '//SOAP-ENV:Envelope'
});
and it is not very efficient because to extract data from one xml tag, i have to write a lot of extra code. I tried using external libs with suitescript but they didn't worked. Is there any better way to convert XML to JSON
I have a project that needs to convert xml to json rencently, so I wrote the following function.
require(['N/xml'], function (xmlMod) {
//This function refer to https://davidwalsh.name/convert-xml-json
function xmlToJson(xmlNode) {
// Create the return object
var obj = Object.create(null);
if (xmlNode.nodeType == xmlMod.NodeType.ELEMENT_NODE) { // element
// do attributes
if (xmlNode.hasAttributes()) {
obj['#attributes'] = Object.create(null);
for (var j in xmlNode.attributes) {
if(xmlNode.hasAttribute({name : j})){
obj['#attributes'][j] = xmlNode.getAttribute({
name : j
});
}
}
}
} else if (xmlNode.nodeType == xmlMod.NodeType.TEXT_NODE) { // text
obj = xmlNode.nodeValue;
}
// do children
if (xmlNode.hasChildNodes()) {
for (var i = 0, childLen = xmlNode.childNodes.length; i < childLen; i++) {
var childItem = xmlNode.childNodes[i];
var nodeName = childItem.nodeName;
if (nodeName in obj) {
if (!Array.isArray(obj[nodeName])) {
obj[nodeName] = [
obj[nodeName]
];
}
obj[nodeName].push(xmlToJson(childItem));
} else {
obj[nodeName] = xmlToJson(childItem);
}
}
}
return obj;
};
var str = '<?xml version="1.0"?><ALEXA VER="0.9" URL="davidwalsh.name/" HOME="0" AID="="><SD TITLE="A" FLAGS="" HOST="davidwalsh.name"><TITLE TEXT="David Walsh Blog :: PHP, MySQL, CSS, Javascript, MooTools, and Everything Else">Hello World</TITLE><LINKSIN NUM="1102">Netsuite</LINKSIN><SPEED TEXT="1421" PCT="51"/></SD><SD><POPULARITY URL="davidwalsh.name/" TEXT="7131"/><REACH RANK="5952"/><RANK DELTA="-1648"/></SD></ALEXA>';
var xmlObj = xmlMod.Parser.fromString({
text: str
});
var jsonObj = xmlToJson(xmlObj.documentElement);
log.debug('jsonObj', jsonObj);
});
The cenvert function referred to David Walsh's function located at: https://davidwalsh.name/convert-xml-json
I just revised it compatible with Netsuite.
Hope it works for you.
Here's a sample function from my NetSuite environment. I did not write this,but it is currently working.
//*********** PARSE XML INTO JSON ***********
function nsXMLToJSON(node){
var obj=nsXMLToJSONDirty(node);
var cleanObj=cleanObject(obj,true);
return cleanObj;
//*********** HELPER FUNCTIONS ***********
function nsXMLToJSONDirty(node){
var obj={};
if(!'nodeType' in node){
return obj;
}
if(node.nodeType==1 || node.nodeType=='ELEMENT_NODE'){
if(Object.keys(node.attributes).length > 0){
obj["#attributes"]={};
for(var j in node.attributes){
var attribute=node.attributes[j];
if(attribute){
obj["#attributes"][attribute.name]=attribute.value;
}
}
}
}else if(node.nodeType==3 || node.nodeType=='TEXT_NODE'){
obj=node.nodeValue;
}
if(node.hasChildNodes()){
var childNodes=node.childNodes;
for(var k in childNodes){
var item=childNodes[k];
var nodeName=item.nodeName;
if(typeof (obj[nodeName])=="undefined"){
obj[nodeName]=nsXMLToJSONDirty(item); //run the function again
}else{
if(typeof (obj[nodeName].push)=="undefined"){
var old=obj[nodeName];
obj[nodeName]=[];
obj[nodeName].push(old);
}
obj[nodeName].push(nsXMLToJSONDirty(item));
}
}
}
return obj;
}
function cleanObject(myobj,recurse){
var myobjcopy=JSON.parse(JSON.stringify(myobj));
for(var i in myobjcopy){
if(recurse && typeof myobjcopy[i]==='object'){
if(i=="#text"){
delete myobjcopy[i];
} else {
//Check if it only contains a text object
if(Object.keys(myobjcopy[i]).length==1){
if(typeof myobjcopy[i]['#text'] != "undefined"){
if(myobjcopy[i]['#text'] || myobjcopy[i]['#text']==0){
myobjcopy[i]=myobjcopy[i]['#text'];
}
}
}else{
//Handle empty objects
if(Object.keys(myobjcopy[i]).length==0){
myobjcopy[i]=undefined;
}
}
if(myobjcopy[i]){
myobjcopy[i]=cleanObject(myobjcopy[i],recurse);
}
}
}
}
return myobjcopy;
}
}
create a helper.js file so the function can be shared across different scripts.
define(["N/xml"], function (xml) {
function xmlToJson(text) {
function xmlNodeToJson(xmlNode, obj) {
var sibling = xmlNode;
while (sibling) {
if (sibling.nodeType == xml.NodeType.COMMENT_NODE) {
sibling = sibling.nextSibling;
continue;
}
if (sibling.nodeType == xml.NodeType.TEXT_NODE) {
if (!!sibling.nodeValue.replace(/[\n| ]/g, ''))
obj[sibling.nodeName] = sibling.nodeValue;
sibling = sibling.nextSibling;
continue;
}
var childObj = Object.create(null);
if (!!sibling.hasAttributes()) {
Object.keys(sibling.attributes).forEach(function (key) {
childObj[key] = sibling.getAttribute({ name: key });
});
}
var value = xmlNodeToJson(sibling.firstChild, childObj);
if ((sibling.nodeName in obj)) {
if (!Array.isArray(obj[sibling.nodeName])) {
obj[sibling.nodeName] = [obj[sibling.nodeName]];
}
obj[sibling.nodeName].push(value);
} else {
obj[sibling.nodeName] = value;
}
sibling = sibling.nextSibling;
}
return obj;
}
var xmlDocument = xml.Parser.fromString({ text: text });
return xmlNodeToJson(xmlDocument.firstChild, Object.create(null));
}
return {
xmlToJson: xmlToJson
}
});
import the helper file and use the xmlToJson function in your script.
define(['N/file', '/SuiteScripts/PATH_TO_HELPER_FILE/helper'], function(file, helper) {
...
var string = file.load({ id: '/SuiteScripts/PATH_TO_FILE/filename.xml' }).getContents()
var json_object = helper.xmlToJson(string);
...
})

I want to implement the hashtable in javascript but it has an exception

function HashTable(){
var size = 0;
var entry = new Object();
this.add = function(key,value){
if(!containsKey(key)){
size++;
}
entry[key] = value;
}
this.getValue = function(key){
return containsKey(key)?entry[key]:null;
}
this.remove = function(key){
if (containsKey(key) && delete entry[key]) {
size--;
}
}
this.containsKey = function(key){
return (key in entry);
}
this.containsValue = function(value){
for(var prop in entry){
if(entry[prop] == value){
return true;
}
}
return false;
}
//get all values
this.getValues = function(){
var values = new Array();
for(var prop in entry){
values.push(entry[prop]);
}
return values;
}
//get all keys
this.getKeys = function(){
var keys = new Array();
for(var prop in entry){
values.push(prop);
}
return keys;
}
this.getSize = function(){
return size;
}
this.clear = function(){
size = 0;
entry = new Object;//???????????????????
}
}
var hashtest = new HashTable();
hashtest.add('name','LiMing');
I want to implement the hashtable in javascript but when I test it ,there is an exception like this:
Uncaught ReferenceError: containsKey is not defined
at HashTable.add (:8:3)
at :64:10
The problem you have is an issue of scope. The javascript interpreter does not know you mean the containsKey from the HashTable class.
When calling functions within the class scope be sure to reference them with "this". So containsKey should be referenced as this.containsKey(key). That way the interpreter knows you are referring to the class' scope and not the local scope.
You should also do this for the variables with class scope. So when you do size++ you should actually write this.size++. Same for entry. If you do not add "this", it will assume it is a local function or variable defined within that function itself.
So you should rewrite your add() function as
this.add = function(key,value){
if(!this.containsKey(key)){
this.size++;
}
this.entry[key] = value;
}
Why are you manually keeping track of the size anyway? You can simply define "entry" as an array and use this.entry.size
Considering the more specific case of the hashmap, I would advice you to simply create two arrays within the object, one for the keys and one for the values, this will drastically simplify the problem for you because then you can simply use the builtin Javascript array functions. Both arrays will have a numerical index but the key and the value will both always have the same index so you can easily math them up. The result would be like this:
function HashTable() {
this.keys = new Array();
this.values = new Array();
this.add = function(key, value) {
if (this.containsKey(key)) {
var index = this.keys.indexOf(key);
this.values[index] = value;
} else {
this.keys.push(key);
this.values.push(value);
}
}
this.containsKey = function(key) {
return this.keys.includes(key);
}
this.containsValue = function(value) {
return this.values.includes(value);
}
this.get = function(key) {
var index = this.keys.indexOf(key);
return this.values[index];
}
this.remove = function(key) {
if (this.containsKey(key)) {
var index = this.keys.indexOf(key);
this.keys.splice(index, 1);
this.values.splice(index, 1);
}
}
this.size = function() {
return this.keys.length;
}
this.clear = function() {
this.keys = new Array();
this.values = new Array();
}
}
// Create hashtable
var hashTable = new HashTable();
// Add some test data
hashTable.add('name', 'LiMing');
hashTable.add('location', 'At home');
hashTable.add('eyes', 'blue');
// Updates the value, doesn't add it
hashTable.add('eyes', 'brown');
console.log(hashTable.get("eyes"));
// Get the size
console.log(hashTable.size());
// Check if a value or key is in the hashtable
console.log(hashTable.containsValue("test")); // False
console.log(hashTable.containsValue("LiMing")); // True
console.log(hashTable.containsKey("name")); // True
console.log(hashTable.containsKey("age")); // False
// Get all the keys and values
console.log(hashTable.keys);
console.log(hashTable.values);
// Remove an item
hashTable.remove('eyes');
console.log(hashTable.keys);
console.log(hashTable.values);
// Clear hashtable
hashTable.clear();
console.log(hashTable.keys);
console.log(hashTable.values);
Use this.containsKey instead, as containsKey is a 'member' method inside the object created by HashTable, you have to reference it with this.
function HashTable(){
var size = 0;
var entry = new Object();
this.containsValue = function(value){
for(var prop in entry){
if(entry[prop] == value){
return true;
}
}
return false;
}
this.add = function(key,value){
if(!this.containsKey(key)){
size++;
}
entry[key] = value;
}
this.getValue = function(key){
return this.containsKey(key)?entry[key]:null;
}
this.remove = function(key){
if (this.containsKey(key) && delete entry[key]) {
size--;
}
}
this.containsKey = function(key){
return (key in entry);
}
//get all values
this.getValues = function(){
var values = new Array();
for(var prop in entry){
values.push(entry[prop]);
}
return values;
}
//get all keys
this.getKeys = function(){
var keys = new Array();
for(var prop in entry){
values.push(prop);
}
return keys;
}
this.getSize = function(){
return size;
}
this.clear = function(){
size = 0;
entry = new Object;//???????????????????
}
}
var hashtest = new HashTable(); hashtest.add('name','LiMing');
console.log(hashtest.getValues())
There's a better way to organize your code using ES6:
class HashTable {
constructor() {
this.size = 0;
this.entry = new Object();
}
containsValue(value) {
for(var prop in entry){
if(this.entry[prop] == value){
return true;
}
}
return false;
}
add(key,value) {
if(!this.containsKey(key)){
this.size++;
}
this.entry[key] = value;
}
getValue(key) {
return this.containsKey(key) ? this.entry[key] : null;
}
remove(key) {
if (this.containsKey(key) && delete this.entry[key]) {
size--;
}
}
containsKey(key) {
return (key in this.entry);
}
//get all values
getValues() {
var values = new Array();
for(var prop in this.entry){
values.push(this.entry[prop]);
}
return values;
}
//get all keys
getKeys() {
var keys = new Array();
for(var prop in this.entry){
values.push(prop);
}
return keys;
}
getSize() {
return this.size;
}
clear() {
this.size = 0;
this.entry = new Object();//???????????????????
}
}
var hashtest = new HashTable(); hashtest.add('name','LiMing');
console.log(hashtest.getValues())

Taking more time to fetch records in json object using javascript function

I have 20000 records, below javascript function taking more time to fetch records in Json object.
$("#txtKey").keyup(function() {
var value = $("#txtKey").val();
var exactMatch = $('#exactMatch').is(':checked');
var key = $("#SearchKey option:selected").val();
var filteredData = vLookup(value, data, key, exactMatch);
fillTableDataDynamic(filteredData);
});
function vLookup(value, data, key, exactMatch) {
if (typeof data === "object" && !(data instanceof Array)) {
var arrData = [];
arrData.push(data);
data = arrData;
}
var filteredData = [];
var transValue = value.toLowerCase();
for (var i = 0; i < data.length; i++) {
if (exactMatch) {
if (JSON.stringify(data[i][key]).indexOf(value) > -1) {
filteredData.push(data[i]);
}
} else {
if (JSON.stringify(data[i][key]).toLowerCase().indexOf(transValue) > -1) {
filteredData.push(data[i]);
}
}
}
return filteredData;
}
Any alternate way to fetch record?
Thanks Advance.
from the look of your data
if (exactMatch) {
if (data[i][key].toString().indexOf(value) > -1) {
filteredData.push(data[i]);
}
} else {
if (data[i][key].toString().toLowerCase().indexOf(transValue) > -1) {
filteredData.push(data[i]);
}
}
will work for you
so - no speed difference
try this: uses Array.prototype.filter - there's extra overhead in the function call, but the filter function may yet achieve speed improvement
function vLookup(value, data, key, exactMatch) {
if (typeof data === "object" && !(data instanceof Array)) {
var arrData = [];
arrData.push(data);
data = arrData;
}
var transValue = value.toLowerCase();
if (exactMatch) {
return data.filter(function(datum) {
return datum[key].toString().indexOf(value) > 1;
});
} else {
return data.filter(function(datum) {
return datum[key].toString().indexOf(transValue) > 1;
});
}
}

(Un)Set nested array values by string input

I have a function like this:
Session.get = function(key) {
if (!window["_SESSION"] || typeof key == 'undefined') {
return window["_SESSION"] || {};
}
if (key.indexOf('.') === -1) {
return window["_SESSION"][key] || {};
}
var keyArr = key.split('.'), val = window["_SESSION"];
for ( var i = 0; i < keyArr.length; i++) {
if (typeof val[keyArr[i]] === 'undefined') {
return null;
}
val = val[keyArr[i]];
}
return val;
}
This function allows me to get nested values without temporary variable outside of the function. Example Session.get('var.nestedvar') is returns value of window[_SESSION']['var']['nestedvar'].
Bat how can I (un)set variables like so? Tried to delete val; but didn't work.. How do the javascript references work? Does anybody know any alternative to accomplish similiar functionality?
You can delete by parent like this:
[10:00:00.380] a = {'root': {'home':'~'}}
[10:00:00.385] ({root:{home:"~"}})
--
[10:00:09.625] b = a['root']
[10:00:09.631] ({home:"~"})
--
[10:00:20.569] delete b['home']
[10:00:20.573] true
[10:00:21.684] a
[10:00:21.688] ({root:{}})
You can use a slight modification of your existing code, like this:
Session.delete = function(key) {
if (!window["_SESSION"] || typeof key == 'undefined') {
return false;
}
if (key.indexOf('.') === -1) {
if (key) {
delete key;
return true;
}
}
var keyArr = key.split('.'), val = window["_SESSION"];
var keyDepth = keyArr.length;
for ( var i = 0; i < keyDepth-1; i++) {
if (typeof val[keyDepth] === 'undefined') {
return null;
}
val = val[keyDepth];
}
if (val[keyDepth-1]) {
delete val[keyDepth-1];
return true;
}
return false;
}

Categories