Search multi-dimensional array JavaScript - javascript

I have an array which looks like this :
selected_products[0]=["r1","7up",61,"Albertsons"]
selected_products[1]=["r3", "Arrowhead",78,"Arrowhead "]
selected_products[2]=["r8", "Betty Crocker Cake Mix (Variety)",109,"Arrowhead "]
...
how can I search for an item in this array according to the first entry in each item (r1,r2,..)
the array is huge I am looking for a fast an effective way to get results from this array
I used the JQuery function jQuery.inArray but it couldn't find any thing in my array , I used it this way :
alert($.inArray(["r1","7up",61,"Albertsons"],selected_products))// it returns -1
alert($.inArray("r1",selected_products))//this also returns -1

If you want it to be fast, you'll want a for loop so that you can break the loop when the match is found.
var result;
for( var i = 0, len = selected_products.length; i < len; i++ ) {
if( selected_products[i][0] === 'r1' ) {
result = selected_products[i];
break;
}
}
Of course this assumes there's only one match.
If there's more than one, then you could use $.grep if you want jQuery:
var result = $.grep(selected_products, function(v,i) {
return v[0] === 'r1';
});
This will give you a new Array that is a subset of the matched items.
In a similar manner, you could use Array.prototype.filter, if you only support modern JavaScript environments.
var result = selected_products.filter(function(v,i) {
return v[0] === 'r1';
});
One other solution would be to create an object where the keys are the rn items. This should give you a very fast lookup table.
var r_table = {};
for( var i = 0, len = selected_products.length; i < len; i++ ) {
r_table[selected_products[i][0]] = selected_products[i];
}
Then do your lookups like this:
r_table.r4;
Again this assumes that there are no duplicate rn items.

So you are trying to find the index of the matched result?, well that changes the things a little bit:
var index=-1;
for(var i = 0, len = selected_products.length; i < len; i++){
if(selected_products[i][0] === "r1"){
index = i;
break;
}
}
if(index > -1){
alert(selected_products[index].join(","));//"r1,7up,61,Albertsons"
}
Note: This will return the first result matched, if you want to get an array containing a list of all indexes:
var results=[];
for(var i = 0, len = selected_products.length; i < len; i++){
if(selected_products[i][0] === "r1"){
results.push(i);
}
}
You can then call (for example) the last 'r1' matched like this selected_products[results[results.length-1]].join(",");

Just to pick up #am not i am's great input. Here is a live example. He solved it. I just wanted to give an example that it works. Hope it helps. This puts the values found from the selected value in 2 input fields.
http://jsfiddle.net/asle/ZZ78j/2/
$(document).ready(function () {
var liste = [];
liste[0] = ["First Name", "12345678", "first.name#testdomain.no"];
liste[1] = ["Second Name", "20505050", "second.nametestdomain.no"];
liste[2] = ["", "", ""];
$("#selger").change(function () {
var valg = ($(this).val());
var telefon;
var epost;
for (var i = 0, len = liste.length; i < len; i++) {
if (liste[i][0] === valg) {
telefon = liste[i][1];
epost = liste[i][2];
$("#tel").val(telefon);
$("#epost").val(epost);
break;
}
}
});
});

Try this,
// returns the index of inner array, if val matches in any array
function findIn2dArray(arr_2d, val){
var indexArr = $.map(arr_2d, function(arr, i) {
if($.inArray(val, arr) != -1) {
return 1;
}
return -1;
});
return indexArr.indexOf(1);
}
function test(){
alert(findIn2dArray(selected_products, 'r8'));
}

You might wanna consider not doing these things in Javascript but in a server sided language (PHP/Java/.NET). In this way you:
Won't have problems with browser incapabilities (Mostly IE errors)
Shorter Javascript code and therefore faster to load.
Your site also works with Javascript turned off.
An example how to do this in PHP:
<?php
function search($array, $key, $value)
{
$results = array();
if (is_array($array))
{
if (isset($array[$key]) && $array[$key] == $value)
$results[] = $array;
foreach ($array as $subarray)
$results = array_merge($results, search($subarray, $key, $value));
}
return $results;
}
?>

You may create index object { r1: 1, r2: 2,..., < search key >: < element index >, ...} and use it for searching.

Related

Algorithm to sort an array in JS

I have an array
var arr= [
["PROPRI","PORVEC"],
["AJATRN","PROPRI"],
["BASMON","CALVI"],
["GHICIA","FOLELI"],
["FOLELI","BASMON"],
["PORVEC","GHICIA"]
] ;
And I'm trying to sort the array by making the second element equal to the first element of the next, like below:
arr = [
["AJATRN","PROPRI"],
["PROPRI","PORVEC"],
["PORVEC","GHICIA"],
["GHICIA","FOLELI"],
["FOLELI","BASMON"],
["BASMON","CALVI"]
]
The context is : these are somes sites with coordinates, I want to identify the order passed,
For exemple, I have [A,B] [C,D] [B,C] then I know the path is A B C D
I finally have one solution
var rs =[];
rs[0]=arr[0];
var hasAdded=false;
for (var i = 1; i < arr.length; i++) {
hasAdded=false;
console.log("i",i);
for (var j = 0, len=rs.length; j < len; j++) {
console.log("j",j);
console.log("len",len);
if(arr[i][1]===rs[j][0]){
rs.splice(j,0,arr[i]);
hasAdded=true;
console.log("hasAdded",hasAdded);
}
if(arr[i][0]===rs[j][1]){
rs.splice(j+1,0,arr[i]);
hasAdded=true;
console.log("hasAdded",hasAdded);
}
}
if(hasAdded===false) {
arr.push(arr[i]);
console.log("ARR length",arr.length);
}
}
But it's not perfect, when it's a circle like [A,B] [B,C] [C,D] [D,A]
I can't get the except answer
So I really hope this is what you like to achieve so have a look at this simple js code:
var vector = [
["PROPRI,PORVEC"],
["AJATRN,PROPRI"],
["BASMON,CALVI"],
["GHICIA,FOLELI"],
["FOLELI,BASMON"],
["PORVEC,GHICIA"]
]
function sort(vector) {
var result = []
for (var i = 1; i < vector.length; i++) result.push(vector[i])
result.push(vector[0])
return (result)
}
var res = sort(vector)
console.log(res)
Note: Of course this result could be easily achieved using map but because of your question I'm quite sure this will just confuse you. So have a look at the code done with a for loop :)
You can create an object lookup based on the first value of your array. Using this lookup, you can get the first key and then start adding value to your result. Once you add a value in the array, remove the value corresponding to that key, if the key has no element in its array delete its key. Continue this process as long as you have keys in your object lookup.
var vector = [["PROPRI", "PORVEC"],["AJATRN", "PROPRI"],["BASMON", "CALVI"],["GHICIA", "FOLELI"],["FOLELI", "BASMON"],["PORVEC", "GHICIA"]],
lookup = vector.reduce((r,a) => {
r[a[0]] = r[a[0]] || [];
r[a[0]].push(a);
return r;
}, {});
var current = Object.keys(lookup).sort()[0];
var sorted = [];
while(Object.keys(lookup).length > 0) {
if(lookup[current] && lookup[current].length) {
var first = lookup[current].shift();
sorted.push(first);
current = first[1];
} else {
delete lookup[current];
current = Object.keys(lookup).sort()[0];
}
}
console.log(sorted);

Select array index by object value

If I have an array like this:
var array = [{ID:1,value:'test1'},
{ID:3,value:'test3'},
{ID:2,value:'test2'}]
I want to select an index by the ID.
i.e, I want to somehow select ID:3, and get {ID:3,value:'test3'}.
What is the fastest and most lightweight way to do this?
Use array.filter:
var results = array.filter(function(x) { return x.ID == 3 });
It returns an array, so to get the object itself, you'd need [0] (if you're sure the object exists):
var result = array.filter(function(x) { return x.ID == 3 })[0];
Or else some kind of helper function:
function getById(id) {
var results = array.filter(function(x) { return x.ID == id });
return (results.length > 0 ? results[0] : null);
}
var result = getById(3);
With lodash you can use find with pluck-style input:
_.find(result, {ID: 3})
Using filter is not the fastest way because filter will always iterate through the entire array even if element being search for is the first element. This can perform poorly on larger arrays.
If you are looking for fastest way, simply looping through until the element is found might be best option. Something like below.
var findElement = function (array, inputId) {
for (var i = array.length - 1; i >= 0; i--) {
if (array[i].ID === inputId) {
return array[i];
}
}
};
findElement(array, 3);
I would go for something like this:
function arrayObjectIndexOf(myArray, property, searchTerm) {
for (var i = 0, len = myArray.length; i < len; i++) {
if (myArray[i].property === searchTerm)
return myArray[i];
}
return -1;
}
In your case you should do:
arrayObjectIndexOf(array, id, 3);
var indexBy = function(array, property) {
var results = {};
(array||[]).forEach(function(object) {
results[object[property]] = object;
});
return results
};
which lets you var indexed = indexBy(array, "ID");

Issues with javascript splice

I have a small piece of code in which i'm trying to splice an item from an array. In below code it should remove item which has "Javascript" and the resulting array should contain only "Java". What am i doing wrong here ?
var autoCompleteArray = new Array();
var item = new Array();
item.push("1");
item.push("Java");
autoCompleteArray.push(item);
var item2 = new Array();
item2.push("2");
item2.push("Javascript");
autoCompleteArray.push(item2);
var val = "Javascript";
for(var i=0;i<autoCompleteArray.length;i++){
if(autoCompleteArray[i][1] == val) {
autoCompleteArray.splice(autoCompleteArray[i],1);
}
}
console.log(autoCompleteArray); //Should show Java in the array since Javascript item has been removed.
You're splicing the wrong thing; this should work:
if(autoCompleteArray[i][1] == val) {
autoCompleteArray.splice(i,1);
}
The first argument to .splice() is the index, not the value at that index.
Be aware that when you splice at index i, for that iteration you should not increase i:
var i = 0;
while (i < autoCompleteArray.length) {
if(autoCompleteArray[i][1] == val) {
autoCompleteArray.splice(i, 1);
continue;
}
++i;
}
This is fine if there can be only one match of course, in which case you can also break; out of the loop.
As #Jack mentioned you need to pass an index (not a value) to splice. I would rewrite your loop as:
for (var i = 0; i < autoCompleteArray.length; i++) {
if (autoCompleteArray[i][1] === val) {
autoCompleteArray.splice(i--, 1);
}
}
That should solve your problem. See the demo here: http://jsfiddle.net/7PM94/
Also note that you can create arrays using the literal syntax instead of pushing elements. You can define autoCompleteArray as follows:
var autoCompleteArray = [
["1", "Java"],
["2", "JavaScript"]
];
Hope that helps.

Find and remove items from object

I have the object below that is used by datatables, I want to know how to remove items by name.
Example
Lets say I want to remove sEcho, mDataProp_1 and sSearch from the object below, would the best way to loop through all items and check the name or is there a easier way.
[{"name":"sEcho","value":1},{"name":"iColumns","value":9},
{"name":"sColumns","value":""},{"name":"iDisplayStart","value":0},
{"name":"iDisplayLength","value":10},{"name":"mDataProp_0","value":0},
{"name":"mDataProp_1","value":1},{"name":"mDataProp_2","value":2},
{"name":"mDataProp_3","value":3},{"name":"mDataProp_4","value":4},
{"name":"mDataProp_5","value":5},{"name":"mDataProp_6","value":6},
{"name":"mDataProp_7","value":7},{"name":"mDataProp_8","value":8},
{"name":"sSearch","value":""},{"name":"bRegex","value":false},
{"name":"sSearch_0","value":""},{"name":"bRegex_0","value":false},
{"name":"bSearchable_0","value":false},{"name":"sSearch_1","value":""},
{"name":"bRegex_1","value":false},{"name":"bSearchable_1","value":false},
{"name":"sSearch_2","value":""},{"name":"bRegex_2","value":false}]
Examples would be great.
Thanks
Here is a little jsfiddle that do just that http://jsfiddle.net/wHkTS/
The idea is to iterate over the area and compare the name you want to remove with the currently iterate object name and basically build a new array to assign back that doesn't contain the object you want to remove.
var data = [
{"name":"sEcho","value":1},{"name":"iColumns","value":9},
{"name":"sColumns","value":""},{"name":"iDisplayStart","value":0},
{"name":"iDisplayLength","value":10},{"name":"mDataProp_0","value":0},
{"name":"mDataProp_1","value":1},{"name":"mDataProp_2","value":2},
{"name":"mDataProp_3","value":3},{"name":"mDataProp_4","value":4},
{"name":"mDataProp_5","value":5},{"name":"mDataProp_6","value":6},
{"name":"mDataProp_7","value":7},{"name":"mDataProp_8","value":8},
{"name":"sSearch","value":""},{"name":"bRegex","value":false},
{"name":"sSearch_0","value":""},{"name":"bRegex_0","value":false},
{"name":"bSearchable_0","value":false},{"name":"sSearch_1","value":""},
{"name":"bRegex_1","value":false},{"name":"bSearchable_1","value":false},
{"name":"sSearch_2","value":""},{"name":"bRegex_2","value":false}
];
function remove(name) {
var arr = [], len, i;
// we reset len as data.length will change after erach remove
for(i = 0, len = data.length; i < len; i++) {
if (data[i].name != name) arr.push(data[i]);
};
data = arr;
};
console.log(data);
remove('sEcho');
console.log(data);
The modern ES5 way is Array.filter:
var original = [{"name":"sEcho","value":1}, ... ];
var filtered = original.filter(function(val, index, array) {
var n = val.name;
return n !== 'sEcho' && n !== 'mDataProp_1' && n !== 'sSearch';
});
I think you'll need to create a function that can search and then remove them, something like
function deleteByName(needle, haystack) {
for(i in haystack) {
if ( haystack[i].name == needle) {
haystack.splice(i,1);
}
}

Removing duplicate element in an array [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Easiest way to find duplicate values in a JavaScript array
Javascript array sort and unique
I have the following array
var output = new array(7);
output[0]="Rose";
output[1]="India";
output[2]="Technologies";
output[3]="Rose";
output[4]="Ltd";
output[5]="India";
output[6]="Rose";
how can i remove the duplicate elements in above array.Is there any methods to do it?
You can write a function like this
function eliminateDuplicates(arr) {
var i,
len=arr.length,
out=[],
obj={};
for (i=0;i<len;i++) {
obj[arr[i]]=0;
}
for (i in obj) {
out.push(i);
}
return out;
}`
Check this here
Maybe more complex than you need but:
function array_unique (inputArr) {
// Removes duplicate values from array
var key = '',
tmp_arr2 = {},
val = '';
var __array_search = function (needle, haystack) {
var fkey = '';
for (fkey in haystack) {
if (haystack.hasOwnProperty(fkey)) {
if ((haystack[fkey] + '') === (needle + '')) {
return fkey;
}
}
}
return false;
};
for (key in inputArr) {
if (inputArr.hasOwnProperty(key)) {
val = inputArr[key];
if (false === __array_search(val, tmp_arr2)) {
tmp_arr2[key] = val;
}
}
}
return tmp_arr2;
}
Code taken from: http://phpjs.org/functions/array_unique:346
You can remove dups from an array by using a temporary hash table (using a javascript object) to keep track of which images you've already seen in the array. This works for array values that can be uniquely represented as a string (strings or numbers mostly), but not for objects.
function removeDups(array) {
var index = {};
// traverse array from end to start
// so removing the current item from the array
// doesn't mess up the traversal
for (var i = array.length - 1; i >= 0; i--) {
if (array[i] in index) {
// remove this item
array.splice(i, 1);
} else {
// add this value to index
index[array[i]] = true;
}
}
}
Here's a working example: http://jsfiddle.net/jfriend00/sVT7g/
For sizable arrays, using an object as a temporary index will be many times faster than a linear search of the array.
First of all, you'll want to use the array literal (var output = []) to declare your array. Second, you'll want to loop through your array and store all the values in a second array. If any value in the first array matches a value in the second array, delete it and continue looping.
Your code would look like this:
var output = [
"Rose",
"India",
"Technologies",
"Rose",
"Ltd",
"India",
"Rose"
]
var doubledOutput = [];
for(var i = 0; i < output.length; i++) {
var valueIsInArray = false;
for(var j = 0; j < doubledOutput.length; j++) {
if(doubledOutput[j] == output[i]) {
valueIsInArray = true;
}
}
if(valueIsInArray) {
output.splice(i--, 1);
} else {
doubledOutput.push(output[i]);
}
}
Please note, the above code is untested and may contain errors.

Categories