ListOrderedMap/ArrayMap like data structure in Javascript - javascript

I'm looking for a JavaScript data structure like ListOrderedMap:
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/ListOrderedMap.html
E.g. It needs to be able add an object at an index, get the index for an object, and able to look up a object by it's id.
All the libraries I could find couldn't add an object at a certain index.

Something like this? Javascript has excellent facilities for arrays and keyed collections, and combinations thereof.
function LAM() {
this.ids = {}
this.indexes = []
}
LAM.prototype.put = function(myObj, id, ix) {
this.ids[id] = myObj
this.indexes[ix] = id
}
LAM.prototype.getByIndex = function(ix) {
return this.ids[this.indexes[ix]]
}
In practice:
? a = new LAM
? a.put("jhgf", "WE", 3)
? a.ids.WE
jhgf
? a.getByIndex(3)
jhgf

Since Javascript doesn't have such the data structure, another solution is to use GWT and use the Java source code of ListOrderedMap.java.

Related

How to fetch values from json array object without using object key name javascript?

Json Array Object
Through Ajax I will get dynamic data which is not constant or similar data based on query data will change. But I want to display charts so I used chartjs where I need to pass array data. So I tried below code but whenever data changes that code will break.
I cannot paste complete JSON file so after parsing it looks like this
[{"brand":"DUNKIN' DONUTS KEURIG","volume":1.9,"value":571757},{"brand":"MC CAFE","volume":1.1,"value":265096}];
You can use Object.keys and specify the position number to get that value
var valueOne =[];
var valueTwo = [];
jsonData.forEach(function(e){
valueOne.push(e[Object.keys(e)[1]]);
valueTwo.push(e[Object.keys(e)[2]]);
})
It seems like what you're trying to do is conditionally populate an array based the data you are receiving. One solution might be for you to use a variable who's value is based on whether the value or price property exist on the object. For example, in your forEach loop:
const valueOne = [];
jsonData.forEach((e) => {
const val = typeof e.value !== undefined ? e.value : e.average;
valueOne.push(val);
})
In your jsonData.forEach loop you can test existence of element by using something like:
if (e['volume']===undefined) {
valueone.push(e.price);
} else {
valueone.push(e.volume);
}
And similar for valuetwo...
You could create an object with the keys of your first array element, and values corresponding to the arrays you are after:
var data = [{"brand":"DUNKIN' DONUTS KEURIG","volume":1.9,"value":571757},{"brand":"MC CAFE","volume":1.1,"value":265096}];
var splitArrays = Object.keys(data[0]).reduce((o, e) => {
o[e] = data.map(el => el[e]);
return o;
}, {});
// show the whole object
console.log(splitArrays);
// show the individual arrays
console.log("brand");
console.log(splitArrays.brand);
console.log("volume");
console.log(splitArrays.volume);
// etc

Can I find an object by the value of one of its properties?

I've got a mother object filled with objects that looks like this:
profiles[ slug ] = {
slug : slug,
url : url,
el : $('#' + el),
position : this.el.position().left
};
I want to be able to reference an object in this array by its position property. Is there any quick way of doing this, save for iterating over all of them and comparing each object's value to what I'm searching for?
Underscore.js has a lot of utilities that help with these types of lookups: http://underscorejs.org/#findWhere
Example code:
var result = _.findWhere(profiles, {position: SEARCH_VALUE});
Is there any quick way of doing this, save for iterating over all of them
Yes: you can build/maintain a secondary index where the key is the position and the value is the object.
index = {};
for (slug in profile) {
if (profile.hasOwnProperty(slug)) {
index[profile[slug].position] = profile[slug];
}
}

Better way to build JSON array and retrieve its elements

Here's how I'm initializing and building an array:
var newCountyInfo = new Object();
newCountyInfo.name = newCountyName;
newCountyInfo.state = newCountyState;
newCountyInfo.zips = newCountyZips;
newCountyInfo.branchID = newCountyBranchID;
So I have my four elements in the array. I'm then passing newCountyInfo to another function to pull out the elements for display in some HTML elements.
The only way I know how to get to the individual elements in the function that uses them is this:
JSON.parse(JSON.stringify(newCountyValidation)).name
JSON.parse(JSON.stringify(newCountyValidation)).state
... etc...
There's got to be a better/shorter/more elegant way of doing this!
What is it?
Why are you serializing at all? I don't understand what JSON has to do with this, unless you're using web workers, ajax, or something else which demands serialization. Start with object literal syntax:
var newCountyInfo = {
name: newCountyName,
state: newCountyState,
zips: newCountyZips,
branchID: newCountyBranchID
};
And just pass the whole object to the other function:
someOtherFunction(newCountyInfo);
Which can access the fields using plain old property accesses:
function someOtherFunction(foo) {
console.log(foo.name); // whatever was in newCountyname
}
No JSON whatsoever.
Something like this should work just fine:
var newCountyInfo = {
name: newCountyName,
state: newCountyState,
zips: newCountyZips,
branchID: newCountyBranchID
}
function test(newCountyValidation)
{
alert(newCountyValidation.name);
}
test(newCountyInfo);

What's the best way to query an array in javascript to get just the items from it I want?

I have an array like this (with just over 3000 objects instead of the 3 here):
items = [{name:'charlie', age:'16'}, {name:'ben', age:'18'}, {name:'steve', age:'18'}]
What's the best way to return an array with just the objects of people who are 18? So I want:
items = [{name:'ben', age:'18'}, {name:'steve', age:'18'}]
The best I can think of is this (using jQuery):
newArray = []
$.each(items, function(index, item) {
if(item.age=='18') {
newArray.push(item)
}
})
Considering that there's 3000 thousand objects, and also that I'll be doing that comparison up to fifty times in one go, that's a lot of looping. Is there a better way?
You can use pure javascript
var wanted = items.filter( function(item){return (item.age==18);} );
And if your browser does not support the 1.6 version of javascript you can find an implementation of the filter method at https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter
Update
Speedwise there is a huge varying (had an error in the test) difference from a normal loop (depending on browser).. Have a look at this little test i made at http://jsperf.com/array-filter-vs-loop/3
Get matched item and items using find() and filter() method
If you want first matched single item, use find() method which returns single object.
If you want all matched , use filter() method which returns array of objects.
let items = [{name:'charlie', age:'16'},
{name:'ben', age:'18'},
{name:'steve', age:'18'}]
let all = items.filter(item=> item.age==='18')
console.log(all);
let single = items.find(item=> item.age==='18')
console.log(single);
If you're going to do the search often it may be best to keep a version of your data in a form that is quick to access.
I've used underscore.js (http://documentcloud.github.com/underscore/) to make it easy for myself, but this code here will create an object that holds your data indexed by the age field.
You end up with something that looks like this:
{
"16": [
{
"name": "charlie",
"age": "16"
}
],
"18": [
{
"name": "ben",
"age": "18"
},
{
"name": "steve",
"age": "18"
}
]
}
The code:
var itemsByAge = _(items).reduce(function(memo, item) {
memo[item.age] = memo[item.age] || [];
memo[item.age].push(item);
return memo;
}, {});
alert(JSON.stringify(itemsByAge["18"]));
No matter which method you choose (items.filter or any "query language" for json), a for loop is inevitable.
If performance is a concern, I would recommend you to use pure javascript instead of libraries like jQuery which will add overheads to the whole processing as is evident here.
Thus, your code would look like:
var newArray = [];
for(var i=0;i<items.length;i++) {
var item = items[i];
if(item.age == '18') {
newArray.push(item);
}
});
making use of javascript magnificent function eval() which evaluates string as code at runtime, we can define a prototype method for Array type
Array.prototype.where = function (query) {
var newArray = [];
for(var i=0; i<this.length; i++) {
var item = this[i];
if(eval( "item" + query )) {
newArray.push(item);
}
}
return newArray;
};
and use it with any array, passing the query as string
var newArray= items.where('.age >= 18');
Use the filter method of the array, it calls the provided callbackfunction once for each element in an array.
array.filter(<callbackfucntion>[, <Object to use>])
once i had such problem and i solved it like this
1- create an array of array
2- each index create an Index record
e.g.
var pAry=[];
var cAry=[{name:'ben', age:'18'}, {name:'steve', age:'18'}]
pAry[17]=cAry;
This way when u require person with age 18, you will get on index 17.

Using jQuery inArray with array of JavaScript Objects

I'm working with an array of JavaScript Objects as such:
var IssuesArray = [{"ID" : "1", "Name" : "Issue1"},
{"ID" : "2", "Name" : "Issue2"},
{"ID" : "3", "Name" : "Issue3"}];
My end effort is trying to remove an object from the array when I know the ID of the object. I'm trying to use code that is something like this:
$.grep(IssuesArray, function(n, i) {
return i != $.inArray("2", IssuesArray);
});
So this shows that I'm trying to use jQuery grep to remove an element by index (i), which I am trying to retrieve by using jQuery inArray. Of course the code above will not work because "2" should correspond to an item in the array, which are all JavaScript objects (an object will never equal "2"). I need something like:
$.inArray(javascriptObject.Name=="2", IssuesArray);
Has anyone ever had any success using inArray to get indexes of JavaScript objects, using a field value within that object? Any help would be appreciated. Thanks.
UPDATE/CLARIFICATION: A couple people have been confused by my question, but I received an answer that works nonetheless. I'm using:
IssuesArray = $.grep(IssuesArray, function(n) {
return n.ID != "2";
});
I think I was thinking about it too deep, when the solution was really pretty easy. I simply wanted to remove a JavaScript object from an array, so long as I knew a particular property's value in that object. The above solution uses jQuery's grep to return everything from the array except any object whose ID == "2". As usual, thanks for the quick answers. A couple answers were good solutions and would have worked using (using "splice", for example), but this solution seems to be the shortest most straightforward. Thanks again.
n is your list item, so something like this should do the job:
$.grep(issuesArray, function(n) { return n.ID != "2"; })
Not sure if I understood your question correctly, but I would do:
$.each(IssuesArray, function(i, item){
if (item.ID == IDToBeRemoved) IssuesArray.splice(i, 1);
});
var spliceID = function(id, arr) {
$(arr).each(function(i, el) {
if (el.ID == id) {
arr.splice(i,1);
return false;
}
});
return arr;
}
console.log(spliceID('2', IssuesArray));
Without using jQuery or other frameworks:
var newArray = [];
var i=0, len=IssuesArray.length;
var bad_id = "2"; // or whatever
while(i<len) {
if(IssuesArray[i].ID !== bad_id) {
newArray.push(IssuesArray[i++]);
}
}
Simplify??
var IssuesArray = {
1: "Issue1",
2: "Issue2",
3: "Issue3"
};
var issue2 = IssuesArray[2];
Why a list of hashes when a single hash will do?

Categories