For example, i have an array like this:
var arr = [
{"keyword": "Sample 1", "item": {"title":"Sample Title", "url": "/sample"}},
{"keyword": "Foo 1", "item": {"title":"Foo Title", "url": "/sample"}}
];
I want to search in the "keyword" key, like when a user presses a key from their input and return that matches objects.
If user presses to "s" key, then first [0], element must return. Like using the SQL LIKE statement.
$("#query").on('keypress', function () {
var result = $.grep(keywords, function(e){
//I do not know what should i do here.
});
});
If you want to use $.grep you can do it like this:
$("#query").on('keyup', function() {
var search = this.value.toLowerCase();
var result = $.grep(keywords, function(el) {
return el.keyword.toLowerCase().indexOf(search) > -1;
});
});
Demo: http://jsfiddle.net/9TPSa/
Also note, that I switched to keyup event to be able to read updated this.value.
Use the Array.prototype.filter method:
Array.prototype.filterBy = function(attr, value) {
return this.filter(function(elem){
return elem[attr].indexOf(value) !== -1;
});
}
Then arr.filterBy('keyword', '1') would return both the objects(in your arr array), while arr.filterBy('keyword', 'oo') would return only the second one.
DEMO
The answer is simple: YOu have to loop through all of your objects, look at each keyword entry and decide wether it matches your search or not. SOmething like this:
var results = [];
for (var i = 0 ; i < arr.length ; i++) {
if (arr[i].keyword == "what ever you are looking for") {
results.push(arr[i]);
}
}
If you only need the frist match (and not all of them), you can simplify it:
var result;
for (var i = 0 ; i < arr.length ; i++) {
if (arr[i].keyword == "what ever you are looking for") {
result = arr[i];
break;
}
}
If you're not looking for equality, but need to use placeholders, take al look at String.prototype.indexOf() or regular expressions.
If you want to use $.grep() at all costs (there isn't too much difference to looping manually though, it does loop as well, just itnernally), you can - it'd look like this:
$("#query").on('keypress', function () {
var result = $.grep(keywords, function(e){
return (e.keyword == "whatever you are looking for again");
// use regular expressions or .indexOf again if you don't want to test equallity
});
});
Looping over large strucutres however (as you're comparing to databases, I suspect you have A LOT of those objects inside arr?) is very inefficient however. The fact that you HAVE TO loop indicates bad design. If you really got a lot of them, you might consider using a data structure that supports indexing, like a Hash Table/Map (those are not implemented in the core Java API; but are easy to implement on yoru own). They won't work if you need placeholders though, they're only an advantage when using equality to match results.
You could try using jQuery UI's AutoComplete... http://jqueryui.com/autocomplete/
You'll have to reduce your array to just the fields you're wanting to be searchable (ie. string literals for the keyword property, like ["Sample 1", "Foo 1"]) and pass that as the source in the autocomplete options.
Then hook into the change event http://api.jqueryui.com/autocomplete/#event-change and pull out the rest of your object from the original array.
EDIT : If you want to use grep, here is an example that gets the results using that method, but how you display them as auto options is then the next step!
http://jsfiddle.net/eQp3h/
var arr = [
{"keyword": "Sample 1", "item": {"title":"Sample Title", "url": "/sample"}},
{"keyword": "Foo 1", "item": {"title":"Foo Title", "url": "/sample"}}
];
$("#query").on('keyup', function () {
var regExp = new RegExp("^" + $(this).val(), "i");
var result = $.grep(arr, function(e, i){
var match = regExp.test(e.keyword);
return match;
});
$("#results").text(JSON.stringify(result));
});
Try this
$("body").on("keyup","#query",function(e){
var str = $("#query").val().toLowerCase();
var newarr = $.grep(arr,function(n,i){
return n.keyword.toLowerCase().search(str)!=-1;
});
});
Related
I've been trying for a while now to search within an array, I've looked at all the other questions that even somewhat resemble mine and nothing works, so I'm asking for any help you can give now..
I have an array with a more complex insides than a simple string array
var elementDefns = [
{"element":"water", "combos": {"air":"steam", "earth":"sand"} },
{"element":"fire", "combos": {"earth":"lava", "air":"energy"} },
{"element":"air", "combos": {"water":"steam", "earth":"dust"} },
{"element":"earth", "combos": {"water":"swamp", "fire":"lava"} },
];
Two elements are picked (by the users) which are combined to create new elements. I'd like to search through the elements for any combos that can be made. Ideally, I'd want to use Array.prototype.find, although I can't figure out how to use polyfills correctly and i'm unsure if i'm writing it correctly, so it continues to not work
var elementOne = $("#board img:first-child").attr('id');
var elementTwo = $("#board img:last-child").attr('id');
function findElement(element) {
return elementDefns.element === elementOne;
}
board is the id div where the element cards go to once clicked. I also tried a loop
for (var i=0, tot=elementDefns.length; i < tot; i++) {
var indexHelp = elementDefns[i].element;
var find = indexHelp.search(elementOne);
console.log(find);
}
I'm trying to post a question that's not too long, but I'm sure there's lots more about my code i need to adjust in order to do this. I guess I'm just asking if there's something obvious you think i could work on. I've looked at most of the answers on this site to similar problems but its all just going horribly wrong so any other support would be greatly appreciated..
I have an array with a more complex insides than a simple string array
Yes, but why? Get rid of the extra layers and this is trivial
var e1 = "water";
var e2 = "air";
var elementDefns = {
"water": {"combos": {"air":"steam", "earth":"sand"} },
"fire": {"combos": {"earth":"lava", "air":"energy"} },
"air": {"combos": {"water":"steam", "earth":"dust"} },
"earth": {"combos": {"water":"swamp", "fire":"lava"} },
};
elementDefns[e1].combos[e2] = > "steam"
If you want to keep your data-structure, you can filter through it like this:
var matches = elementDefns
.filter(e => e.element == first && e.combos[second] !== null)
.map(e => e.combos[second]);
The first row filters out all matches, and the secon maps it over to the actual match-string (element name). The find() you speak of just returns the first value that matches, and i guess you want all, so that would be the filter() method.
Problem
I know how to find out if a string contains a substring like this where you are looking for one word:
var s = "define foo";
alert(s.indexOf("define") > -1);
But how could I check for multiple different words/substrings using an array?
Example not working code that makes sense in my mind but doesn't work:
query = "Define what is grape juice and how to drink it?"
var terms = ["define", "what is", "how to"];
alert(query.indexOf(terms) > -1);
Thanks~!
Try this out:
var phrase = 'texttexttexttexttexttexttext';
var terms = ['word1', 'word2', 'word3'];
function check(string) {
var match = false;
for(var i=0;i<terms.length && !match;i++) {
if(string.indexOf(terms[i]) > -1) {
match = true;
}
}
return match;
}
//example
if(check(phrase)) {
//iftrue
} else {
//iffalse
}
You can use $.each() in jQuery to iterate through the terms array, and check each of them individually against the string. In the code below, I create a new JSON object called matchedTerms that will log the term and its index in the string. See demo here: http://jsfiddle.net/teddyrised/ktuuoprp/1/
var query = "Define what is grape juice and how to drink it?",
terms = ["define", "what is", "how to"],
matchedTerms = [];
$.each(terms, function(i,v) {
var match = query.indexOf(v);
matchedTerms.push({
'term': v,
'index': match
});
});
Even better: you can build a conditional statement in there so that the matchedTerms will only produce a simple array. See demo here: http://jsfiddle.net/teddyrised/ktuuoprp/2/
var query = "Define what is grape juice and how to drink it?",
terms = ["define", "what is", "how to"],
matchedTerms = [];
$.each(terms, function(i,v) {
var match = query.indexOf(v);
if(match > -1) matchedTerms.push(v);
});
console.log(matchedTerms);
p/s: If you want to perform case-insensitive matches, it helps to convert the query into lowercase, i.e. newQuery = query.toLowerCase(query);
You want to see if an array includes a string. There are a few ways to do it. This is answered well here.
Here are 2 options, copied from there:
Option 1:
$.indexOf is effectively a wrapper for Array.prototype.indexOf in browsers that support it (almost all of them these days), while providing a shim in those that don't. It is essentially equivalent to adding a shim to Array.prototype, which is a more idiomatic/JSish way of doing things. MDN provides such code. These days I would take this option, rather than using the jQuery wrapper.
Option 2:
jQuery offers $.inArray:
var found = $.inArray('specialword', categories) > -1;
Note that inArray returns the index of the element found, so 0 indicates the element is the first in the array. -1 indicates the element was not found.
Example.
I have an array of object (JSONized). Something like this :
popUpList = [{
"id":1,
"Name":"My Pop Up",
"VideoUrl":"www.xyz.com/pqr",
"AddToBasketUrl":"www.abc.com?addtoBaketid=1",
"addedToBasket": true
},
{
"id":2,
"Name":"My 2nd Pop Up",
"VideoUrl":"www.xyz.com/mno",
"AddToBasketUrl":"www.abc.com?addtoBaketid=2",
"addedToBasket": false
}]
My situation is a clip can be either added from he pop up or the main page. So, I need to edit the JSON object when something is added to basket from the page.
I tried using $.inArray() and similar methods. i reckon either I am not doing it the right way or missing something. Or, this cannot work for JSON objects and I have to loop through every object.
Any help will be appreciated.
Array.indexOf (what $.inArray is) does need the element to search for and returns its index.
If you need to search for an element you don't know before, you will need to loop manually (Libs like Underscore have helpers):
var idToSearchFor = …;
for (var i=0; i<popUpList.length; i++)
if (popUpList[i].id == idToSearchFor) {
// do something
}
If you want to build an index for faster accessing popups, you can do that as well. It also has the advantage of being unambiguous (only one element per id):
var popUpsById = {};
for (var i=0; i<popUpList.length; i++)
popUpsById[popUpList[i].id] = popUpList[i];
if (idToSearchFor in popUpsById)
// do something with popUpsById[idToSearchFor]
else
// create one?
I'm not quite sure what you want to search explicitely, you can access each value in your object by using:
vat id = "1";
// this given example wont work for you bec. of your structure
// but its all about the idea.
var objectOne = yourJsonObject[id];
// You can also append them
var myValue = yourJsonObject.address.zip;
And similiar on any other item of the fetched first object.
For that I would create a custom search function which would look like that:
$.each(popUpList, function(i, v) {
var entryYouWantToFind = "addedToBasket";
if(v[entryYouWantToFind])
{
// do your stuff here.
}
}
});
I hope I could give you the hint.
Assume you have an array:
var arrStateCityAll=['CA_Alameda','CA__Pasadena','CA_Sacramento','NY_Albany','NY_Buffalo','NY_Ithaca']
Is there an easy way using javascript and/or jQuery to filter the arrStateCityAll to get a new array (a subset of arrStateCityAll); something like this:
// return's ['CA_Alameda','CA__Pasadena','CA_Sacramento']
var arrStateCityCA=FilterArray('CA',arrStateCityAll);
Likely you want to do a regex on each item. You can do this with jQuery's grep function.
http://api.jquery.com/jQuery.grep/
You can use javascript's Array.filter.
var arrStateCityAll = ['CA_Alameda','CA__Pasadena','CA_Sacramento','NY_Albany','NY_Buffalo','NY_Ithaca']
var arrStateCityCA = arrStateCityAll.filter( function (element) {
return element.indexOf("CA_") == 0;
});
The mozilla documentation linked to above has a solution for browsers that don't implicitly support filter.
This should work.
var arrStateCityCA = [];
for (var i = 0;i<arrStateCityAll.length;i++){
if (arrStateCityAll[i].substr(0,2) == 'CA'){
arrStateCityCA.push(arrStateCityAll[i]);
}
}
You could use jQuery.grep
var arrStateCityCA =
$.grep(arrStateCityAll,function(el,i){return (el.substring(0,2)=='CA')});
Demo at jsfiddle
To implement you actual FilterArray function as shown in your post you could do
function FilterArray(state,arr){
return $.grep(arr,
function(el,i) {return (el.substring(0,2)==state)}
);
}
This makes a few assumptions.
State is always 2 chars.
State is always the first 2 chars.
And of course remember case-sensitivity (this function is case sensitive) ie 'CA' not equal to 'Ca'.
if you are going to have an undescore between your state and city name, you can split on the underscore and test against the first array value
function getSubSetByState(set,state) {
var result = [];
for(var i=0,l=set.length;i<l;++i) {
if(set[i].split('_')[0] === state) {
result.push(set[i]);
}
}
return result;
}
Use if by giving it the set of places, and then the state you are searching for.
I'm using $.grep() to pull back a set of JSON results like so:
myObject.appJSON = jQuery.grep(myObject.appJSON, function (a) {
return a.category == "Entertainment";
});
and it works fine. But what I really want to do eventually is have several checkboxes so that that I can filter on several different things. I realize to do that I can just do something like:
myObject.appJSON = jQuery.grep(myObject.appJSON, function (a) {
return (a.category == "Entertainment" && a.category == "Business");
});
But my real question here is how to have this happen dynamically, so I can essentially build up a string of features for the grep to return. Maybe I'm showing how novice I am here but it would almost be nice to be able to generate the long filter string then just pop it into the return. It looks like as it is now, the return has to be hard coded.
I realize this is probably simple but there's very little out there on the net about how to do this kind of thing.
Thanks in advance!
You can search an array like this:
myObject.appJSON = jQuery.grep(myObject.appJSON, function (a) {
return $.inArray(a.category, someArray) > -1;
});
I think you can regexp the match:
var filter = function(categories) {
var obj = [];
$.each(categories.split(' '), function(cat) {
obj.push(jQuery.grep(myObject.appJSON, function (a) {
return cat.test(a.category);
}));
});
return obj;
}
var filtered_array = filter('Entertainment Business');
You could use eval() to create your grep logic dynamically. Or you could create a regular expression matching all your categories. But the easiest thing to do is create an object which contains your categories and check if a.category is one of them.
var categories = {
"Entertainment": 1,
"Business": 1
};
myObject.appJSON = jQuery.grep(myObject.appJSON, function (a) {
return categories[a.category];
});