How do I return an array of indexes in contents that match the pattern.
var contents = ["Dog is big","Cat is small","Horse is huge"]
(contents,"og") //returns [0,2]
(contents,"at") //returns [1]
(contents,"..") //etc
So, "o" and "g" are both in 0 and 2 but not in 1.
note: the letters don't have to be in that order.
You can use Array.prototype.reduce and Array.prototype.every to filter out the indices which matches your criteria - see demo below:
var contents = ["Dog is big","Cat is small","Horse is huge"];
function filter(filter) {
var f = filter.split('');
return contents.reduce(function(p,c,i){
f.every(e=>~c.indexOf(e)) && p.push(i);
return p;
},[]);
}
console.log(filter("og"));
console.log(filter("at"));
Use Array#forEach and Array#every methods.
var contents = ["Dog is big", "Cat is small", "Horse is huge"]
console.log(get(contents, "og"));
console.log(get(contents, "at"));
console.log(get(contents, ".."));
function get(arr, str) {
// array for storing result
var res = [];
// iterate over string array
arr.forEach(function(v, i) {
// split string into individual character and
// check for each for match
// if all elements matched push the element
if (str.split('').every(function(v1) {
return v.indexOf(v1) > -1;
}))
res.push(i);
});
return res;
}
Related
I have referred to this article, but not what I wanted. convert object keys and values to an array of objects
I have the following data:
var test = {
apple1:"a",
apple2: "b",
apple3: "c",
v1r:'1',
v2r:'2',
v3r:'3',
v4r:'4',
a1:'5'
}
My attempts:
var keys = Object.keys(test);
var result = keys.reduce((cur,item)=>{
if(/^\d+$/.test(item)){
let obj = {}
obj[item] = test[item]
}
return cur
},[])
It's not what I wanted.
The results I expect are as follows:
let result = [{apple1:'a',v1r:'1',a1:'5'},{apple2:'b',v2r:'2'},{apple3:'c',v3r:'3'},{v4r:'4'},]
Thank you very much for your help!
A very basic (and very generic) approach is just checking if there is a number in the property and then add the value to an object at the respective index. Of course, this will probably lead to undesired results, if the property names don't follow the rules
var test = {
apple1:"a",
apple2: "b",
apple3: "c",
v1r:'1',
v2r:'2',
v3r:'3',
v4r:'4',
a1:'5'
}
let a = [];
for (let p of Object.keys(test)) {
let m = p.match(/(\d+)/);
if (!m) continue;
var e = a[+m[1]] || {};
e[p] = test[p];
a[+m[1]] = e;
}
a = a.filter(x => !!x)
console.log(a);
Steps for each iteration (using Array#reduce)
Get the number from the key
Get the object from the array with the same index as the number
If the object doesn't exist, create it and add it to the array
Add the key and the value to the array
After the reduce call you can use .filter(Boolean) to remove any empty values created by gaps in the numbers in the keys
var test = {
apple1: "a",
apple2: "b",
apple3: "c",
v1r: "1",
v2r: "2",
v3r: "3",
x9y1: false
};
var result = Object.entries(test).reduce(function(result, [key, value]) {
// Get the number (step 1)
var index = /(\d+)[^\d]*$/.exec(key);
if (!index || !index[1]) return result;
index = +index[1];
// Get the object from the array (step 2)
var item = result[index];
// Add it if it doesn't exist (step 3)
if (!item) result[index] = item = {};
// Add the key and the value (step 4)
item[key] = value;
return result;
}, []).filter(Boolean);
console.log(result);
Edit: if you want to get the last number in the key instead of the first, you can use this regex /(\d+)[^\d]*$/ instead, you will also have to change the index, since you will be accessing the first matched group (\d+) instead of the whole regex match.
I am trying to filter some data from an array in a JSON file, based on an input of the form string1, string1,string2, string1,string2,string3 etc., that is, some strings separated by a ,.
What I'm trying to do:
let arrInput = document.getElementById('inputBox').val.split(',');
for(let i = 0; i < arrToFilter.length; i++){
if(.........what to write here?...........){
arrOutput.push(arrToFilter[i]);
}
}
return arrOutput;
If the arrInput had a fixed length, I could accomplish this using indexOf != -1 for each element in arrInput, but here, since the length of arrInput is variable, how can I check if at least one of the strings present in arrInput is also present as a substring in arrToFIlter[i]?
Edit:
Example:
Let arrToFilter be ["abcqwer", "pizza", "definition", "abcdef", "example"]
Case 1 :
Say the input entered (in an <input> element) is abc,def.
For this, the arrOutput should be ["abcqwer", "definition", "abcdef"]
Case 2:
Say the input entered is abc
Expected output : ["abcqwer", "abcdef"]
Simple way is using some and filter,
var string = 'ad,kk,sb';
var array = ['adik', 'klop', 'pp'];
var stringers = string.split(',');
var result = array.filter((arr) => {
var isPresent = stringers.some(stringer => arr.includes(stringer));
return isPresent ? true : false;
});
console.log(result);
You need to iterate both arrays
let arrToFilter = ['abcqwer', 'pizza', 'definition', 'abcdef', 'example'];
let arrOutput = [];
let arrInput = document.getElementById('inputBox').value.split(',');
arrToFilter.forEach(filter => {
arrInput.forEach(input => {
if (!!input && filter.includes(input)) {
arrOutput.push(filter);
}
});
});
// distinct the output
return arrOutput.filter((v, i, a) => i === a.indexOf(v));
I have to write a function that returns all users with a second letter of "h" in their name.
var users = ["Roman","Sherry","Sandrah","Shamaika"];
I started to code something like this but it is not working.
function letter(){
var index = users.indexOf("h") == [1];
return(index);
}
I am new to JavaScript and I am not sure where to start.
You can use filter.
const users = ["Roman","Sherry","Sandrah","Shamaika"];
let filteredUsers = users.filter(user => user.charAt(1) === 'h');
console.log(filteredUsers);
You could filter the array by taking a function which check the character at index 1.
function checkLetter1(string) {
return string[1] === 'h';
}
var users = ["Roman", "Sherry", "Sandrah", "Shamaika"];
console.log(users.filter(checkLetter1));
You are missing filter
var users = ["Roman","Sherry","Sandrah","Shamaika"];
var index = users.filter(a=> a.indexOf("h") === 1);
console.log(index);
You can do something like so:
function usersWithSecondH(users) {
return users.filter(user => user[1] === 'h');
}
So essentially checking the value of the second letter and returning those names in a new array if it matches 'h';
var users = ["Roman","Sherry","Sandrah","Shamaika"];
var t=users.filter((x)=>x.indexOf('h')==1)
console.log(t);
This will do
Currently, your code is looking for the first index of h in the array of user names, which will return incorrect results. Consider using the Array#filter method to select names that match your criteria of the second character being h like so:
var users = ["Roman","Sherry","Sandrah","Shamaika"];
function letter(name){
// Return true if the second character of name is an 'h'
return name[1] === 'h';
}
// Use filter() method to get array of items that satisfy
// the criteria of your letter() function
var filteredUsers = users.filter(letter);
console.log(filteredUsers);
The following function will return the array elements (as a result array) which have the second character as a "h":
var users = ["Roman", "Sherry", "Sandrah", "Shamaika"];
function getMyUsers() {
return users.map(user => user.split(""))
.filter(userChars => userChars[1] == "h")
.map(userChars => user.join(""));
};
console.log(getMyUsers());
The Output:
[ "Sherry", "Shamaika" ]
EDIT: The getMyUsers function can also be coded in a more detailed way as follows:
function getMyUsers2() {
let usersWithH = [];
for (let user of users) {
let userChars = user.split("");
if (userChars[1] == "h") {
usersWithH.push(user);
}
}
return usersWithH;
}
console.log(getMyUsers2()); // prints [ "Sherry", "Shamaika" ]
I am trying find out the matching element of an array for a given string.
var array = ["CODE1", "CODE2", "CODE3", "CODE4", "CODE5", "CODE6"];
var text = "alsdjklfjaaCODE2ladkslfj";
var resultCode;
for (var i in array) {
if (text.indexOf(array[i]) > -1) {
resultCode = array[i];
}
}
console.log(resultCode);
But I felt that it is not efficient way to iterate through array as that array was little big. Is there any alternative algorithm for my problem.
As of ES6, you can use Array.prototype.find and Array.prototype.includes
var array = ["CODE1", "CODE2", "CODE3", "CODE4", "CODE5", "CODE6"],
text = "alsdjklfjaaCODE2ladkslfj";
var resultCode = array.find(a => text.includes(a));
document.write(resultCode);
You can use Array.prototype.some()
The some() method tests whether some element in the array passes the test implemented by the provided function.
if you expect only one match in the string. The iteration stops if the callback returns true.
var array = ["CODE1", "CODE2", "CODE3", "CODE4", "CODE5", "CODE6"],
text = "alsdjklfjaaCODE2ladkslfj",
resultCode;
array.some(function (a) {
if (~text.indexOf(a)) {
resultCode = a;
return true;
}
});
document.write(resultCode);
Given an array of strings:
x = ["banana","apple","orange"]
is there a built in shortcut for performing wildcard searches?
ie., maybe
x.indexOf("*na*") //returns index of a string containing the substring na
Expanding on Pim's answer, the correct way to do it (without jQuery) would be this:
Array.prototype.find = function(match) {
return this.filter(function(item){
return typeof item == 'string' && item.indexOf(match) > -1;
});
}
But really, unless you're using this functionality in multiple places, you can just use the existing filter method:
var result = x.filter(function(item){
return typeof item == 'string' && item.indexOf("na") > -1;
});
The RegExp version is similar, but I think it will create a little bit more overhead:
Array.prototype.findReg = function(match) {
var reg = new RegExp(match);
return this.filter(function(item){
return typeof item == 'string' && item.match(reg);
});
}
It does provide the flexibility to allow you to specify a valid RegExp string, though.
x.findReg('a'); // returns all three
x.findReg("a$"); // returns only "banana" since it's looking for 'a' at the end of the string.
Extending on #Shmiddty's answer, here are useful JavaScript ideas:
Extend Array with a new method: Array.prototype.method = function(arg) { return result; }
Filter arrays using: Array.filter(function(e) { return true|false; })
Apply formula to elements in an array: Array.map(function(e) { return formula(e); })
Use regular expressions: either /.*na.*/ or new Regex('.*na.*')
Use regular expressions to match: let result = regex.test(input);
Use Array.prototype.reduce to aggergate a result after running a function on every element of an array
i.e. I prefer the input argument to be a regex, so, it gives you either:
A short but universal pattern matching input,
e.g. contains, starts with, ends width, as well as more sophisticated matches
The ability to specify an input pattern as a string
SOLUTION 1: filter, test, map and indexOf
Array.prototype.find = function(regex) {
const arr = this;
const matches = arr.filter( function(e) { return regex.test(e); } );
return matches.map(function(e) { return arr.indexOf(e); } );
};
let x = [ "banana", "apple", "orange" ];
console.log(x.find(/na/)); // Contains 'na'? Outputs: [0]
console.log(x.find(/a/)); // Contains 'a'? Outputs: [0,1,2]
console.log(x.find(/^a/)); // Starts with 'a'? Outputs: [1]
console.log(x.find(/e$/)); // Ends with 'e'? Outputs: [1,2]
console.log(x.find(/pear/)); // Contains 'pear'? Outputs: []
SOLUTION 2: reduce, test
Array.prototype.find = function(regex) {
return this.reduce(function (acc, curr, index, arr) {
if (regex.test(curr)) { acc.push(index); }
return acc;
}, [ ]);
}
let x = [ "banana", "apple", "orange" ];
console.log(x.find(/na/)); // Contains 'na'? Outputs: [0]
console.log(x.find(/a/)); // Contains 'a'? Outputs: [0,1,2]
console.log(x.find(/^a/)); // Starts with 'a'? Outputs: [1]
console.log(x.find(/e$/)); // Ends with 'e'? Outputs: [1,2]
console.log(x.find(/pear/)); // Contains 'pear'? Outputs: []
You can extend the array prototype to find matches in an array
Array.prototype.find = function(match) {
var matches = [];
$.each(this, function(index, str) {
if(str.indexOf(match) !== -1) {
matches.push(index);
}
});
return matches;
}
You can then call find on your array like so
// returns [0,3]
["banana","apple","orange", "testna"].find('na');
using regex can do this in javascript
var searchin = item.toLowerCase();
var str = columnId;
str = str.replace(/[*]/g, ".*").toLowerCase().trim();
return new RegExp("^"+ str + "$").test(searchin);
In addition to everything else that has been said, you can do this:
var x = ["banana", "apple", "orange"];
var y = [];
for (var i in x) {
if (x[i].indexOf('na') > -1) {
y.push(i);
}
}
Results: y = [0]