Check if string is in array inside dictionary - javascript

I have a dictionary of strings to arrays of strings: {"a":["b", "c"]}. When indexing into the dictionary, I get an array of strings back, but checking if any string is in this array always returns false.
Here is the code setup:
var dict = {
"first":["a", "b", "c"]
}
if("a" in dict["first"]){
// Never hits this line
console.log("Found a!");
}
I'm pretty new to Javascript so I may be missing something about the setup of a dictionary object, but it seems pretty straightforward and I have professional experience in a few C languages so it is fairly disconcerting that this doesn't work. What is wrong here?

The in operator returns true if the specified property is in the specified object, Taken from here.
a is not a property it's an array value, array index is act as property and 0 in dict["first"] will be true here. So here you can use indexOf()
var dict = {
"first": ["a", "b", "c"]
}
if (dict["first"].indexOf("a") > -1) {
console.log("Found a!");
}

try this. this will work to you.
var dict = {
"first":["c", "b", "a"]
};
console.log(dict.first);
for( var x in dict.first){
if(dict.first[x]=="a")
{
console.log("index of a :"+ x);
break;
}
}
}

Related

Find best matching array in set of arrays using Jquery or Javascript

I have a very unique condition to search.
I have one array
["A","B","C"]
I need to search best matching array in this set of arrays :
[
["A"],
["B"],
["C"],
["F"],
["A","D"],
["A","B","E"],
["B","C","E"],
["A","B"],
["C","E"],
["A","B","D","E","C"]
]
Intended result for this search will be ["A","B","D","E","C"] as this contains all items from search array.
Actually I need to return minimum number of arrays as possible and shortest and must contain all items from search array.
If I am looking for ["B","C","F"] then its should return ["B","C","E"] and ["F"]. It returns ["B","C","E"] but not ["A","B","D","E","C"] because ["B","C","E"] has less number of unwanted item like "E" which is not required in search.
It might require some kind of algorithm. but I tried so hard finding some logic to perform this task, but was unsuccessful. could anyone have any idea about this, please let me know. Thank you.
so, the way i see it, you need to loop through the array of arrays and compare each array to the original array. you can give it a score, adding one with each individual element in the arrays that match up. then, you hold on to the one with the 'highest score' and return that. so, i'll give you some quick pseudocode and leave it to you to try to work it out. if you need more help, just respond and i'll give you the full code.
function findArray(original, arrList){
// first declare variables that you need
let bestArrMatch;
let bestArrScore = -1;
// loop through array of arrays
for (let i = 0; i < arrList.length; i++){
// we're using a function called score here. we'll have to define it later
// but for now let's assume it works by returning a score of number of similar items in the two arrays
let newArrScore = score(original, arrList[i]);
if (newArrScore > bestArrScore){
bestArrMatch = arrList[i];
bestArrScore = newArrScore;
}
}
return bestArrMatch;
}
// Now, of course, we used a function called 'score' earlier. write the function
function score(a, b){
// i'll let you figure out most efficient way to to compare two arrays
// hint: try sorting
}
Let me know if this helps a little! And let me know if I can help more!
Try using this simple approach:
var keys = ["A", "B", "C"]
var input = [
["A"],
["B"],
["C"],
["F"],
["A", "D"],
["A", "B", "E"],
["B", "C", "E"],
["A", "B"],
["C", "E"],
["A", "B", "D", "E", "C"]
]
function findMinArrayHavingAllKeys(inputArr, searchKeys) {
//initialize an empty array, here we will keep
//override the shortest array having all keys
var outputArray = [];
// iterating over the outer array and taking each inner array to perform the logic
inputArr.forEach(function(inputSubArr) {
//if any key is not found in the inner array !inputSubArr.includes(key) will true and break
//the iteration, and return true, and that will be negate to false. if all keys found in the
//input array, it will return false and we will negate to true the final result to consider
var consider = !searchKeys.some(function(key) {
return !inputSubArr.includes(key);
});
//if array is considerable and (either shorter than the result we got so far or we don't have
//a result yet) then we are overriding the ourput result
if (consider && (outputArray.length > inputSubArr.length || !outputArray.length)) {
outputArray = inputSubArr;
}
});
//at the end we are returning the output array, if no elements having all the keys then output will
//be empty array, otherwise output will be the shortest first array, in case you want all the shortest
//array of same length we can maintain aanother array of array and push inputSubArray into that array
return outputArray;
}
console.log('output: ', findMinArrayHavingAllKeys(input, keys));
Comment if anything is not clear
You could first create a hash keyed by each letter that occurs in the set of arrays, so that for each letter you know in which of these arrays it occurs. This will save you some look-up time.
Then use a recursive function, that for each letter in the search array will check in which sub array it occurs, and try each of these as possible options and for each recurse for doing the same with the next letter in the search array. If any such letter is already accounted for by a previously selected array, then just take the next search character.
When all search characters have been scanned in that way, you'll have a subset of the set of arrays. Then check if the number of these sub arrays is less than what you found thus far. If so it is the best solution so far. The rest of the recursive search might still improve on the best solution.
Here is the ES6 code for doing this. It gives the output you expect for the two example searches you mentioned in the question:
function getHash(choices) {
// Return a map keyed by values (letters), providing the subarrays
// in which those values occur
return choices.reduce((hash, choice) =>
choice.reduce((hash, val) =>
hash.set(val, (hash.get(val) || []).concat([choice]))
, hash)
, new Map());
}
function bestMatch(search, hash) {
let best = [];
(function recurse(i, set, arrays) {
// find next search value that is not yet accounted for:
while (set.has(search[i])) i++;
// See if we have all the values searched for:
if (i >= search.length) {
// If this solution has fewer arrays, take it as best so far:
if (!best.length || arrays.length < best.length) best = arrays;
return;
}
// Try with one of the sub arrays that has this value, and recurse...
hash.get(search[i]).forEach( arr =>
recurse(i+1, new Set([...set, ...arr]), arrays.concat([arr]))
);
})(0, new Set(), []); // start with first search letter and empty results
return best;
}
// Sample input
const choices = [
["A"],
["B"],
["C"],
["F"],
["A","D"],
["A","B","E"],
["B","C","E"],
["A","B"],
["C","E"],
["A","B","D","E","C"]
],
hash = getHash(choices),
searches = [
["A","B","C"],
["B","C","F"]
];
// Report the solution for each of the search arrays:
for (const search of searches) {
console.log(JSON.stringify(search), ': ',
JSON.stringify(bestMatch(search, hash)));
}

Check array to see if it contains one of the two specified values

I need help with figuring out whether an array contains strings other than two specific strings. For example, if a string has anything other than "a", it should fail. Case sensitivity is not important.
var array = ["a", "a", "a", "b"]; // this should fail
var array2 = ["a", "a", "a", "a"]; // this should pass
I was thinking of something like this:
var abFound = false;
// Run a for loop and look for the contents of the array element (indexOf) to see if it equals "a" or "b", if it does set abFound to true.
Any suggestions or better way of doing it?
Thanks.
The function Array.prototype.some can be used to iterate over an array, testing each element of that array against a supplied predicate, and returning true as soon as the predicate returns true.
var not_A = array.some(function(s) {
return s !== 'a';
});
If the predicate returns false for every element in the array then the eventual return value of .some is also false.
You can also use Array.prototype.every which has the opposite behaviour - it returns false as soon as any predicate test fails, and only returns true if the predicate returns true for every element of the array:
var all_A = array.every(function(s) {
return s === 'a';
});
Using Array.prototype.filter is inefficient, since it is required to test every single element in the array with no opportunity to terminate early as soon as a contra-indicating result is found.
Filter based on the element not being equal to whatever you are checking for, and check if it's length is 0.
var not_a = array.filter(function(value) { return value != 'a' }).length != 0;
You can try this
var filtered = array.filter(function(value){
return value === 'a';
});
if(filtered.length === array.length){
console.log("pass")
} else{
console.log("fail")
}

NodeJS Difference Object.keys(array).length and array.length

I have a function which reads Files from the file system and stores them into an array. Afterwards I want to add a key/value pair to that element. However, the forEach loop is not executed, because apparently there is no element in there.
readFilesFromDirectory(folder, elements, 'json', function(){
log(Object.keys(elements).length,0);
log(elements.length,0);
elements.forEach(function(elem){
elem["newKey"] = 1;
});
});
My log contains the following lines:
1
0
The first length method is working, the second is not.
I would like to know what I am doing wrong for the second function and how I can fix it.
Actually, my main objective is to add the new key. However, I do not know how to use some Object.keyValues(elements).forEach(function(elem){...} in my code. If you have a hint for that, this would also be nice.
I would really appreciate some insight here! :-)
The Object.keys() method returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
Object.keys returns an array whose elements are strings corresponding to the enumerable properties found directly upon object. The ordering of the properties is the same as that given by looping over the properties of the object manually.
var arr = ["a", "b", "c"];
alert(Object.keys(arr)); // will alert "0,1,2"
// array like object
var obj = { 0 : "a", 1 : "b", 2 : "c"};
alert(Object.keys(obj)); // will alert "0,1,2"
// array like object with random key ordering
var an_obj = { 100: "a", 2: "b", 7: "c"};
alert(Object.keys(an_obj)); // will alert "2, 7, 100"
// getFoo is property which isn't enumerable
var my_obj = Object.create({}, { getFoo : { value : function () { return this.foo } }});
my_obj.foo = 1;
alert(Object.keys(my_obj)); // will alert only foo

Return unique keys from JavaScript Array

I'm hoping my question is using the correct terminology...
Can someone explain to me how I can perform the following:
If I have an array consisting of:
Object { id=1498, brandName="Booths", quality="Standard"}
Object { id=1499, brandName="Booths", quality="Standard"}
How can I iterate throughout that array and return another array of distinct 'keys'?
Ultimately I want an array which would return something like:
[id,brandName,quality] (but the original array is going to return different keys at different times.
Have I made sense?
You can use Object.keys:
var a1 = [{ id:1498, brandName:"Booths", quality:"Standard"},
{ id:1499, brandName:"Booths", quality:"Standard"}],
a1Keys = a1.map(function(a){return Object.keys(a);});
//a1Keys now:
[['id','brandName','quality'],['id','brandName','quality']]
The keys method is described #MDN, including a shim for older browsers
var a = {"a": 1, "b": "t" };
var keys = new Array();
for(var o in a){
keys.push(o);
}
console.log(keys)

Reach into a JavaScript array object

If I console log test
I get
[
{
property_1: "a",
property_2: "b",
}
]
How can I console log the value of property_1 ?
console.log(test[0].property_1);
test is an array, who's first element is a map with keys property_1, and property_2.
test[0] accesses the first element of the array, which is a map. From there you can directly access the properties with the dot notation, or with a string subscript:
console.log(test[0]["property_1"]);
console.log(test[0]["property_1"])
First go into the array:
my_arr[0]
Then to get the property:
my_arr[0]['property_1']
End result:
var my_arr = [
{
property_1: "a",
property_2: "b",
}
]
alert(my_arr[0]['property_1']);
If that's what you get when you console.log, then I'd bet that you have a JSON string that needs to be parsed.
If so, do this...
var parsed = JSON.parse(test);
alert(parsed[0].property_1);

Categories