I'm trying to search through a list of multiple values.
Here is the an example of the values:
[
{
"color":"blue",
"medium":"Sculpture",
"place":"Garage"
}
{
"color":"red",
"medium":"Painting",
"place":"Pool"
}
]
Below is my code. Works great to find a single value. But I need to find multiple values. For example I need to look and find the results for queries such as: "red blue" or "blue Painting".
It should return results that have both word.
I don't really know how to solve this, does anybody have an idea?
Thanks a lot
function search(){
var search = $('#search').val();
if(search.length < 1) {
return null;
};
var searches = search.split(" ");
var fields = ["color","medium","place"];
var results = [];
$.each(searches, function(i, word){
var wordResult = searchInJson(word,fields,json);
if( wordResult.length > 0 ) {
results.push(wordResult);
}
});
var results = searchInJson(searches,fields,json);
displaySearchResults(results);
};
function searchInJson(search,fields,json) {
var regex = new RegExp(search);
var results = [];
$.each(json, function(i, image){
$.each(fields, function(j, fieldname){
var field = image[fieldname];
if (regex.test(field)) {
results.push( image );
}
});
});
return results;
}
Here's a quick method to try:
var list = [
{
"color":"blue",
"medium":"Sculpture",
"place":"Garage"
},
{
"color":"red",
"medium":"Painting",
"place":"Pool"
}
];
var search = "red painting";
var results = list.filter(function (el) {
var s = search.toLowerCase().split(" ");
for (var key in el) {
for (var i=0; i < s.length; i++) {
if (el[key].toLowerCase() == s[i]) { // this could use indexOf depending on if you want to match partial words
s.splice(i,1);
i--;
if (!s.length) return true;
}
}
}
return false;
});
console.log(results);
Related
I am trying to write an application that searches an array of functions and does the function that was found.
var search = 'test';
var valid_input_array = [
function test(){console.log('test');},
function abc(){console.log('abc');}
];
for (i = 0; i < valid_input_array.length; i++) {
if (valid_input_array[i].name === search) {
valid_input_array.search;
}
}
It does find the function but it doesn't run it.
You need to call found function
var search = 'test';
var valid_input_array = [function test(){console.log('test');},function abc(){console.log('abc');}];
for(i = 0; i < valid_input_array.length; i++){
if(valid_input_array[i].name === search){
valid_input_array[i]()
}
}
You could also use Array#find()
var search = 'test';
var valid_input_array = [
function test(){console.log('test');},
function abc(){console.log('abc');}
];
var funcWanted = valid_input_array.find(function(fn) {
return fn.name === search
})
// only call it if find doesn't return false
funcWanted && funcWanted()
I have an array like this
var userdata = [
{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active"},
{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active"},
{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active"},
{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Inactive"}
]
I need to filter this array on some conditions. The form of these conditions are like this.
var search_object = {gender:"M",city:"Seattle, WA"}
// Gender = M and city = 'Seattle, WA'
var search_object1 = {gender:"M"}
var search_object2 = {city:"Seattle, WA"}
// This is same as above
var search_array = {status:["Active","Inactive"]}
// Status Active or Inactive
var search_array = [{status:"Active"},{status:"Inactive"}]
// Same as above
var search_object1 = {gender:"F"}
var search_array = [{status:"Active"},{status:"Inactive"}]
//Gender = F and status = Active or Inactive
var search_object = {gender:"F"}
var search_array = [{status:["Active","Inactive"]}]
// same as above
I have tried looping but failed. Please help or suggest or provide some proper links to get help.
The following code covers all the cases you mentioned.
function search(searchObj, data) {
if(searchObj instanceof Array) {
return data.reduce(function(prev, current, index, array) {
return prev.concat(search(current, data));
}, []);
} else {
var results = data.filter(function(el) {
for(var prop in searchObj) {
if(searchObj[prop] instanceof Array) {
if(searchObj[prop].indexOf(el[prop]) == -1) {
return false;
}
} else
if(el[prop] !== searchObj[prop]) {
return false;
}
}
return true;
});
return results;
}
};
search(search_object, userdata);
Here is the working example in JSFiddle.
And here are some links to the functions I've used above:
Array.prototype.reduce()
Array.prototype.concat()
Array.prototype.filter()
Array.prototype.indexOf()
Just what RGraham said in the comments, you can use the filter function on arrays.
var search_object = {gender:"M",city:"Seattle, WA"};
var filtered = userdata.filter(function(obj){
return (obj.gender === search_object && obj.city === search_object.city)
});
filtered[0];//Array with objects that return true;
I have an array of objects. Every object in the array has an id and an item property that is an array containing other object. I need to be able to find an element in an array by id. Here is a sample of what I have done so far, but the recursive function is always returning undefined.
How can I quit the function and return the item when I have called the function recursively several times?
$(function () {
var treeDataSource = [{
id: 1,
Name: "Test1",
items: [{
id: 2,
Name: "Test2",
items: [{
id: 3,
Name: "Test3"
}]
}]
}];
var getSubMenuItem = function (subMenuItems, id) {
if (subMenuItems && subMenuItems.length > 0) {
for (var i = 0; i < subMenuItems.length; i++) {
var item;
if (subMenuItems[i].Id == id) {
item = subMenuItems[i];
return item;
};
getSubMenuItem(subMenuItems[i].items, id);
};
};
};
var searchedItem = getSubMenuItem(treeDataSource, 3);
alert(searchedItem.id);
});
jsFiddle
You should replace
getSubMenuItem(subMenuItems[i].items, id);
with
var found = getSubMenuItem(subMenuItems[i].items, id);
if (found) return found;
in order to return the element when it is found.
And be careful with the name of the properties, javascript is case sensitive, so you must also replace
if (subMenuItems[i].Id == id) {
with
if (subMenuItems[i].id == id) {
Demonstration
Final (cleaned) code :
var getSubMenuItem = function (subMenuItems, id) {
if (subMenuItems) {
for (var i = 0; i < subMenuItems.length; i++) {
if (subMenuItems[i].id == id) {
return subMenuItems[i];
}
var found = getSubMenuItem(subMenuItems[i].items, id);
if (found) return found;
}
}
};
I know its late but here is a more generic approach
Array.prototype.findRecursive = function(predicate, childrenPropertyName){
if(!childrenPropertyName){
throw "findRecursive requires parameter `childrenPropertyName`";
}
let array = [];
array = this;
let initialFind = array.find(predicate);
let elementsWithChildren = array.filter(x=>x[childrenPropertyName]);
if(initialFind){
return initialFind;
}else if(elementsWithChildren.length){
let childElements = [];
elementsWithChildren.forEach(x=>{
childElements.push(...x[childrenPropertyName]);
});
return childElements.findRecursive(predicate, childrenPropertyName);
}else{
return undefined;
}
}
to use it:
var array = [<lets say an array of students who has their own students>];
var joe = array.findRecursive(x=>x.Name=="Joe", "students");
and if you want filter instead of find
Array.prototype.filterRecursive = function(predicate, childProperty){
let filterResults = [];
let filterAndPushResults = (arrayToFilter)=>{
let elementsWithChildren = arrayToFilter.filter(x=>x[childProperty]);
let filtered = arrayToFilter.filter(predicate);
filterResults.push(...filtered);
if(elementsWithChildren.length){
let childElements = [];
elementsWithChildren.forEach(x=>{
childElements.push(...x[childProperty]);
});
filterAndPushResults(childElements);
}
};
filterAndPushResults(this);
return filterResults;
}
I have a sample code:
function getKeyword() {
var instance = this;
var googlePattern = /(www\.google\..*)/;
this.params = function(parameters) {
var result = [];
var params = parameters.split("&");
for(var p in params) {
var kv = params[p].split("=");
result[kv[0]] = kv[1];
}
return result;
};
this.googleKeywords = function(params){
var query = params["q"];
var pattern = /"(.*?)"|(\w+)/g;
return decodeURIComponent(query).replace(/\+/g, " ").match(pattern);
};
this.parseReferrer = function(){
var result = [];
var pathAndParams = document.referrer.split("?");
if(pathAndParams.length == 2) {
var path = pathAndParams[0];
var params = this.params(pathAndParams[1]);
if(path.search(googlePattern) > 0) {
result = this.googleKeywords(params);
}
}
return result;
};
return this.parseReferrer();
}
And then:
<script type="text/javascript">
if (document.referrer && document.referrer != "") {
if (document.referrer.search(/google\.*/i) != -1){
var keyword = getKeyword();
alert(keyword);
} else {
alert('Not search from google');
}
} else {
alert('Not referrer');
}
</script>
Ex: when i search with keyword is "iphone 5", result not show alert("iphone 5") ? How to fix it ?
The JavaScript for in construct loops over more than just the entries in the array. If you want to use for in you need to make sure that you're only processing the actual parameters. This is easiest accomplished by checking for hasOwnProperty:
this.params = function(parameters) {
var result = [];
var params = parameters.split("&");
for(var p in params) {
if (params.hasOwnProperty(p))
{
var kv = params[p].split("=");
result[kv[0]] = kv[1];
}
}
return result;
};
Alternatively you can use a regular for loop over the array:
this.params = function(parameters) {
var result = [];
var params = parameters.split("&");
for(var i=0; i < params.length; i++) {
var kv = params[i].split("=");
result[kv[0]] = kv[1];
}
return result;
};
I am currently doing this but it isn't working:
var tempArray=new Array();
var number = 15;
tempArray[number]='blabla';
for (var key in tempArray) {
alert(tempArray[key]);
}
the output that I get is:
in_array function (element) { var retur = false; for (var values in this) { if (this[values] == element) { retur = true; break; } } return retur; }
What am I doing wrong?
In JavaScript we use Objects.
var obj = {};
obj["15"] = "blabla";
obj.fifteen = "blablah";
for(var i in obj) {
alert(obj[i]);
}