Search for a string in a list of strings - javascript

I have a list of strings & I want to check that a specific string is not found in it.
I use javascript, so I was wondering if a Trie or binary search method would be better. Is there something pre-implemented that can be used for something like this ?
Here is the object :
var TheObject = { "TheItemId": Index, "TheItemText": NewItem };
I have a list of this objects, when I insert a new Item, I want to be sure "TheItemText" doesn't contain any similar texts.

JavaScript objects can be treated as hash-maps. So you would keep an object var strings = {}. Whenever you add object to the list, you would also add property to the strings object: strings[text] = true. Then you can easily check whether the text has been added before with if (strings[text]) {. Downside of this solution is that you must track changes in two collections (your list and strings). Maybe you do not need list at all, then you can use strings[NewItem] = { 'TheItemId': Index, 'TheItemText': NewItem }. Changes to 'TheItemText' and the property name must be still coordinated.

Wouldn't something like this work?
typeof TheList.TheItemText === 'undefined'

Related

How to eliminate the values from array if it contains specific characters/string in JavaScript/lodash?

I am having one array with some values like below,
let a = ["Mango","1243greatApple","goodOrange","Watermelon","ThisGoodalsoberemoved","GreatOrange","Pappaya","BestApple"];
Now, I want to eliminate the values which contains string like Great and Good in the values.
Expecting output like below,
["Mango","Watermelon","Pappaya","BestApple"]
Tried using lodash, but it works only when it matches exact string. But i need it like regex match. Please help me out with this.
In vanilla JS, you can try with Array.prototype.filter()
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
And String.prototype.includes()
The includes() method determines whether one string may be found within another string, returning true or false as appropriate.
let a = ["Mango","1243GreatApple","GoodOrange","Watermelon","ThisGoodalsoberemoved","GreatOrange","Pappaya","BestApple"];
var r = a.filter(f => !(f.includes('Great') || f.includes('Good')));
console.log(r);

Get nth element of a key in an object

I'd like to return the third node (hello3.com) of the key hello.com in javascript object.
nodes = {
"hello.com":
{
id:"hello1.com",
id2:"hello2.com",
id3:"hello3.com"
}
}
I know that I can fetch all the key/values like this:
newobject = nodes["hello.com"];
but how would I get the third. I'm aware that you can't count on the order in an object. If not, can I pull just the third by maybeb id3.
You answered your own question when you said that you can't count on the properties of an object to be in any certain order. If your properties are sequential in nature (your properties were counting up in your example), then I would suggest trying to use an Array.
nodes = {
"hello.com": [
"hello1.com",
"hello2.com",
"hello3.com"
]
};
In the above example, you would access the 3rd property with
nodes["hello.com"][2]
The double bracket notation is because "hello.com" is in quotes to allow a . in the name. If the key didn't require quotes, like helloCom as an example, you could use
nodes.helloCom[2]
Beyond this, if you name your keys sequentially, then you can impose an "order". It's not that any property is literally before or after another, but rather that you have informed yourself of what order YOU intend them to be.
You can try this,
nodes = {
"hello.com": {
id: "hello1.com",
id2: "hello2.com",
id3: "hello3.com"
}
}
console.log(nodes["hello.com"]["id3"]);
Use:
nodes['hello.com'].id3 or nodes['hello.com']['id3']
Both are corrent way to get id3 data from given object
BY INDEX :
About accessing by index, you can not achieve it directly. the closest you can get is array of keys but that also do not guarantee the order of keys returned. See this answer provided on other thread.
for (var i in nodes["hello.com"]) { console.log(i);//logs id,id2,id3 };
BY NODENAME:
nodes["hello.com"] returns object. You can use key to access the value by
1) using dot notation:
nodes["hello.com"].id3
2) or by bracket notation
nodes["hello.com"]["id3"]
Try one of the following expressions
nodes["hello.com"]["id3"]
or
nodes["hello.com"].id3

Javascript multidimensional arrays with alphanumeric keys

This seems to be a common source of confusion from what I've seen, and apparently I'm no exception. I've read a few tutorials on this, and I still can't quite get my head around it. From what I can gather, Arrays are objects in Javascript, just like Strings and other variable types. But I still don't get how that helps me declare a multidimensional array with alphanumeric keys.
In PHP I can simply write:
$calendar = array();
foreach ($schedule->currentExhibitions as $key) {
$calendar[$key["ExhibitionID"]]["startDate"] = date("Y,n,j", strtotime($exhibition["StartDate"]));
$calendar[$key["ExhibitionID"]]["endDate"] = date("Y,n,j", strtotime($exhibition["StartDate"]));
}
But in Javascript trying something similar will create errors. Should I create an Array and fill it will Objects? If so, how would I go about doing so? Or should I just use an Object entirely and skip having any sort of Array? (If so, how do I create a multidimensional Object?)
Sorry for the newbish quesion!
If your keys are strictly numerical and ordered starting at zero, then an array makes sense and you can use square bracket notation just like you would in php, although you will need to initialize sub-arrays if you want to have multiple dimensions :
var myArray = [];
myArray[0] = [];
myArray[0][0] = "something interesting";
If your keys are not numerical, ordered and starting at zero, then you should use an object (all keys are strings), which still allows the square bracket notation :
var myObject = {};
myObject["1A"] = {};
myObject["1A"]["3B"] = "something interesting";
In Javascript, an array is an object, who's keys are numerical, sequential, indexes.
As soon as you want to use alpha-numerica (aka strings) keys, you use a regular object.
In JS to do what you want, you'd do the following (using more or less your php code).
var calendar = {};
Object.keys(schedule.currentExhibitions).forEach(function(key) {
var ex = schedule.currentExhibitions[key];
calendar[ex.exhibitionId] = calendar[ex.exhibitionId] || {}; //if the key doesn't exist, create it.
calendar[ex.exhibitionId].startDate = date(); //some js date function here
calendar[ex.exhibitionId].endDate = date(); //your js date function here
});
I look at Multidimension as nesting, and at multiple levels of nestings as complex objects. For example:
var parent = [];//top holder
var child1 = {};
child1.name = "Jim";
parent.push(child1);
In this simple example, you can access child1 like this:
parent[0]["name"] //Jim
So that is, in a way, multidemensional. Instead of using ["name"] as an indexer, or child1 as an object it could also be an array, like this:
var parent = [];//top holder
var child1 = [];
child1.push("Jim");
parent.push(child1);
In this example, you could get Jim with:
parent[0][0];//Jim
So for complex examples you may have multiple levels of these nestings (or dimensions).
parent[0]["Child"].grandChild[5]["cousin"].name //etc
Where that would just be a continuation of the previous examples down the line.
If you want to preserve order or you want to access by numeric index, use an array. The value of the array can be a single value or an object or array itself (so each value in the array can contain more than a simple value).
If you want to access by a unique alphanumeric key, then use an object and assign properties to it.
Arrays have numeric indexes. They do not have alphanumeric indexes.
Objects have string keys.
Because an array is also an object, it can have both types of keys, but using a string key is not an array access, it's accessing a property of the object.
When you ask for the .length of an array, you only get the length of the numeric indexes. It does not include other properties of the object.
An array of objects is a very practical data structure in javascript and is used quite often when either order or index by numeric index is important.
If order is not important or you don't need to access by numeric index and just want to access by an alpha numeric string, then you should just use an object and set a properties on it with keys that are your alphanumeric string.

Array type being picked up as array value

I have some simple Javascript looping through an array of items (Tridion User Groups) to check if the user is a member of a specific group.
I can easily code around the issue shown below ( see && extensionGroup !== 'true') but I want to understand why the isArray = true is counted as a value in the array - any ideas?
The screenshot below demonstrates that the value extensionGroups has been set thus
var extensionGroups = ["NotEvenARealGroup", "Author", "ExampleGroupAfterOneUserIsActuallyIn"];
but returns the isArray value as a 4th value?
updated to show images a little clearer
You're using for in to iterate an array; don't do that. Use for (or forEach):
for(var i = 0; i < extensionGroups.length; i++) {
var extensionGroup = extensionGroups[i];
// ...
}
The reason this fails is because for in is used to iterate over an object's properties in JavaScript. Iterating over an array in this way means you get anything else assigned to it, such as this property or length.
And if you're able to use Array#forEach, it's probably most appropriate here:
extensionGroups.forEach(function(extensionGroup) {
// ...
});
For..in, technically speaking, doesn't iterate through values. It iterates through property names. In an array, the values ARE properties, under the hood. So when you iterate over them with for..in you get funky stuff like that happening.
Which highlights my next point: don't use for..in. Don't use it for arrays -- don't use it for anything, really. Ok -- maybe that's going a bit too far. How about this: if you feel the need to use for..in, think hard to see if it's justifiable before you do it.

How to access fields in JSON object by index

I know this isn't the best way to do it, but I have no other choice :(
I have to access the items in JSONObject by their index. The standard way to access objects is to just wirte this[objectName] or this.objectName. I also found a method to get all the fields inside a json object:
(for (var key in p) {
if (p.hasOwnProperty(key)) {
alert(key + " -> " + p[key]);
}
}
(Soruce : Loop through Json object).
However there is no way of accessing the JSONfields directly by a index. The only way I see right now, is to create an array, with the function above, get the fieldname by index and then get the value by fieldname.
As far as I see it, the p (in our case the JSON file must be an iteratable array to, or else the foreach loop wouldn't work. How can I access this array directly? Or is it some kind of unsorted list?
A JSON Object is more like a key-value-map; so, yes, it is unsorted. The only way to get around is the index->property name map you've already mentioned:
var keysbyindex = Object.keys(object);
for (var i=0; i<keysbyindex.length; i++)
alert(object[keysbyindex[i]]);
But why would you need these indexes? A unsorted map also has no length property, as an Array had. Why don't you use the for-in-loop
var counter = 0; // if you need it
for (var key in object) {
alert(object[key])
counter++;
}
? If you have a parsed JSON object, i.e. a plain JS Object, you won't have to worry about enumerable prototype properties.
Based on Bergis anserwer this is my solution:
var keysbyindex = Object.keys(this);
alert(this[keysbyindex[index]]);
return this[keysbyindex[index] || ""];
However, I think (not tested) it's extremly bad regaring performace and shouldn't be used! But desperate times require desperate measures.....
I don't think you can actually achieve this without creating your own parsing of JSON. You're writing that you want to go trough a JSON-object, but what you're actually trying to do is go trough a plain old Javascript object. Json is simply a string-representation used to transfer/store said object, and in here lies the main problem: the parser that transforms the string into an actual object (ie. the browser in most cases) can chose to ignore the order it finds the properties if it want to. Also, different browsers might have different approaches to parsing JSON for all you know. If they simply use a hash-map for the object that it's simple to loop through it, but the order won't be dependent on the order of the keys in the file, but rather the keys themselves.
For example, if you have the json {"b":"b","a":"a"} and do the for in loop, under some implementations you might end up with a comming first, and in others you might end up with b.
var jsn = {keyName: 'key value result come here...'};
var arr = jsn ? $.map(jsn, function (el) { return el }) : [0];
console.log(arr[0])
$('.result').text(arr[0]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="result"></span>

Categories