which approach is best to search object in array? - javascript

I've sorted following ways to search for an object in array.
This question has been asked like countless times but I want to know which of the best from following ways. If there's another I'd like to know that too.
Using $.grep()
function is_in_array(arr,element){
var result = $.grep(arr, function(e){ return e.id == element; });
return result.length;
}
Above function returns length of array.
0 when element not present
1 when element present
length > 1 if more elements with same value present
using lookup object
var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
lookup[array[i].id] = array[i];
}
This way I don't need to traverse entire array each time. I'd just check for lookup[id] instead.
for loop in traditional way
function in_array(array, id) {
for(var i=0;i<array.length;i++) {
if(array[i].id === id) {
return true;
}
}
return false;
}
to check if element exists, i'd call in_array(arr,element).
Which approach is best ? Question seriously sounds duplicate and it is but I just want to make sure which is best from these three only.
Update
Array will contain objects like --
var arr = [];
var nameObj = {};
nameObj.label = "somename";
nameObj.id = 123;
arr.push(nameObj);
.
.
.

You could also use a combination of JSON (for comparison) and the Array.filter method:
var findvalue = JSON.stringify([somevalue]),
,found = [array].filter(
function(a){return JSON.stringify(a) === findvalue;}).length
;
// found > 0 means: findvalue found
A jsfiddle example
More about Array.filter and a shim for older browsers #MDN

You could use the built-in map() method instead of a loop:
var lookup=array.map(function(e){return e.id;});
(Not supported in IE 8)

Related

Modern query method for multidimensional js [array of arrays] other than nested for loops

I have an array [arr] within an array of arrays [ [arr], [arr1], [arr2] ]
e.g.["prague",50,14] in the following arrays array that I want to check for:
[
["prague",50,14],
["vienna",48.2, 16.4],
["bratislava",48.15, 17.1]
]
and ideally I want to query this [arrays] array using a single parameter ["prague",50,14] to find out if my item already exists before deciding whether to add a new item or not to avoid duplicates:
check existing [arrays] array to ensure [arr] does not exist
if [arr] not found, add/push new item into [arrays] array
​
current nested for method
Now the way I currently do this is by iterating the arrays array and in turn looping though each element
for (var i = 0; i < arr.length; i++) {
for (var k = 0; k < arr[i].length; k++) {
if (arr[i][0] == "prague" && arr[i][1] == 50 && arr[i][2] == 14){
console.log(arr[i][0]+", "+arr[i][1]+", "+arr[i][2]); // if item exists already
} else {
// code to add new item
}
}
}
​which in itself is not ideal either as if (arr[i][0] == "prague" && arr[i][1] == 50 && arr[i][2] == 14) produces multiple results (see below code snippet)
​
looking for a modern approach
Before I get flooded with "duplicate" post responses I just want to say that I have looked around extensively and read tonnes of posts here on SO etc about arrays, multidimensional arrays, many which were actually objects, and so on but I'm still none the wiser.
I haven't really found a good question/answer using a simple and similar array example so hence I've decided to create this additional post about querying multidimensional js arrays (not object arrays) in the hope they will aid code dabblers like myself 😉
I'm convinced there should be a far simpler modern way to do this
which is mainstream acceptable and far easier then my traditional
solution.
​
tried to no avail
At first I thought I could do this using Javascript include() method e.g. arr.includes([p1,p2,p3]) or jQuery inArray() method e.g. $.inArray([p1,p2,p3], arr) but neither seems to work.
I suspect it's because these methods don't work with multidimensional arrays like the one I'm dealing with here, right?
Perhaps I should look at a combination of the above coupled with my "traditional" method, perhaps it may improve code readability or perhaps there really is no better way. In any case I'd be grateful to see how peeps on here handle these type of multidimensional array queries.
​
code snippet
// our array of arrays
var arr = [];
arr.push(["prague",50,14]);
arr.push(["vienna",48.2, 16.4]);
arr.push(["bratislava",48.15, 17.1]);
// params to check for
var p1 = "prague", p2 = 50, p3 = 14;
console.log("Check for Params: "+p1+", "+p2+", "+p3)
console.log("Expected values: as above ||\"true\" || \"int\" other than -1");
console.log("Our array of arrays:\n", arr);
console.log("_________________________________________________________");
console.log("Current nested for loop method:")
for (var i = 0; i < arr.length; i++) {
for (var k = 0; k < arr[i].length; k++) {
if (arr[i][0] == "prague" && arr[i][1] == 50 && arr[i][2] == 14){
console.log(arr[i][0]+", "+arr[i][1]+", "+arr[i][2]); // if item exists already
} else {
// code to add new item
}
}
}
console.log("_________________________________________________________");
console.log("[Failed using: jQuery inArray() method");
var prague = $.inArray([p1,p2,p3], arr);
console.log(prague);
console.log("_________________________________________________________");
console.log("[Failed using: Javascript includes() method");
var prague2 = arr.includes([p1,p2,p3]);
console.log(prague2);
var prague3 = arr.includes(p1,p2,p3);
console.log(prague3);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You could stringify the requested array and the items of the given data.
Then find the item.
var data = [["prague", 50, 14], ["vienna", 48.2, 16.4], ["bratislava", 48.15, 17.1]],
request = ["prague", 50, 14],
json = JSON.stringify(request),
item = data.find(a => JSON.stringify(a) === json);
console.log(item);

Using 2 arrays of objects, iterate over them using something similar to IndexOf (or other option)

I have an array of objects, i was trying to iterate over. The array is pretty simple in format.
{a:5, b:"key", c:19}
i was trying to compare an array with a subset, say: [{a:5},...]
for (var i = 0; i < subset.length; i++) {
var searchTerm = subset[i].a;
var index = objs.indexOf(searchTerm, function (el) {
return el.a;
});
if (index > -1) {
objs[index].Found = true;
}
}
So that way ultimately objs, could have a new key in it, 'Found'
This way, it will set the main array objs item.Found = true, if it existed in subset.
There are 2 issues though. Accounting for multiple instances of the same item, and the fact that this current implementation doesnt seem to work.
This is a slight expansion of (indexOf method in an object array? )but with an array of search terms.
ideally, i dont want to change the arrays at all, so im trying not to slice, etc.
In a lot of the defintions, indexOf is defined as:
function indexOf (key, start);
instead of the ideas i am trying to work with.
Edit
Here is some code that i have to get this working, but i was thinking there is a more effecient way to do it than written.
for (var j = 0; j < compare.length; j++){
var searchTerm = compare[j]["a"];
for (var k = 0; k < objs.length; k++){
if (!objs[k].Found && objs[k]["a"] == searchTerm){
objs[k].Found = true;
break;
}
}
}

Get the length of an array within a JSON object

I want to find out how many items are in my JSON object. I have seen many answers but they all deal with a common value to loop through. I am wanting the results to tell me that there are 2 items in this object. Any help would be great!
[{"manager_first_name":"jim","manager_last_name":"gaffigan"}]
You could use Object.keys in newer browsers. It would return an array of all the keys in the object, and that array would have a length property that will tell you how many items there are in the object :
var arr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}];
var length = Object.keys(arr[0]).length;
FIDDLE
In non-supporting browsers, you have to iterate
var arr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}];
var i = 0;
for (var key in arr[0]) i++;
FIDDLE
You can do this:
var arr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}],
length = 0,
obj = arr[0]; // Get first obj from array
for(var k in obj){
if( obj.hasOwnProperty(k) ) {
length++;
}
}
console.log(length); // Shows 2
You should use hasOwnProperty because you can also extend an Object with functions, there could otherwise also be count als keys.
Links:
hasOwnProperty
Try
var jsonArr = [{"manager_first_name":"jim","manager_last_name":"gaffigan"}];
var itemCount = JSON.stringify(jsonArr).split('":"').length - 1;
This is, of course, a rather coarse(and unreliable) way of doing it, but if you just want the item count, this should work like a charm.

Filtering a JavaScript array [duplicate]

This question already has an answer here:
How to filter a javascript object array with variable parameters
(1 answer)
Closed 9 years ago.
I am looking for a way to filter my JavaScript Array() columns where the parentId is equal to a variable passed into the method.
// Array decleration
var columns = []; // Columns
//...
for (var i1 in columns) {
if (columns[i1].parentId == listItem) {
//...
Could anybody recommend the easiest way to filter this using either plain JavaScript or jQuery to avoid using the if statement as shown above?
var filteredColumns = columns.filter(function(column) {
return column.parentId == listItem;
});
array = [1,2,3,4,5];
result = $.grep(array, function(n,i) {
return n > 3;
});
This will return an array of filtered elements where the results are greater than 3. Here n is the element in consideration, and i the index of the element. So as per your requirement, the code can run like this:
resultArray = $.grep(columns,function(n,i) {
return n == parentId;
});
Use ES5 Array's filter method:
var filtered = columns.filter(function (item) {
return item.parentId === listItem
});
In the link above there is also a shim for old browsers.
You can also doing that manually:
var filtered = [];
for (var i = 0, item; item = columns[i++];)
if (item.parentId === listItem) filtered.push(item);
Don't use for…in to iterate over Array.

How to remove duplicate objects from java script array?

I have two arrays as shown below. I want to remove Array2 elements from Array1. How do I do that?(either in plain java script or using ExtJS)
var Array1 = [];
var Array2 = [];
Array1.push(['eth0'], ['eth1']);
Array2.push(['eth1']);
If you have the array filter function available to you, you can do something like the following:
var filteredArr = Array1.filter(function(val){
return Array2.indexOf(val) != -1;
})
I think this will only be supported in newer browsers, though. It's an elegant way to handle the situation, so you may want to take a look at a library like UnderscoreJS which will include filtering, defaulting to the native implementation if available.
If using UnderscoreJS, the code would look very similar:
var filterdArr = _.filter(Array1, function(val) {return Array2.indexOf(val) != -1});
function removeDupes(a1, a2) {
var index = {}, result = [], i, l;
for (i=0, l=a2.length; i<l; i++) {
index['-' + a2[i]] = "";
}
for (i=0, l=a1.length; i<l; i++) {
if (index['-' + a1[i]] !== "") result.push(a1[i]);
}
return result;
}
The index object is for speedy look-up of values so we can test their existence quickly.
The '-' + is to migrate the fact that values could be things like toString that also exist as object properties. When prefixed with a letter that regular JavaScript identifiers cannot start with, every value will be safe for use as an object key.
Example:
removeDupes([1,2,3,4], [2,4,5]);
// -> [1,3]
removeDupes([2,4,5], [1,2,3,4]);
// -> [5]
Check this link: http://www.developersnippets.com/2008/10/30/remove-duplicates-from-array-using-javascript/. Concat your arrays with concat() and call uniqueArr().

Categories

Resources