Let's says I've an array['Alex', 'Sam', 'Robert']
I'd like to combine them something like:
Take first array[0] and append with array[2] which will be AlexRobert
first letter of array[0] which is A and append with array[2] that is Robert which will be ARobert
Take array[0] which is Alex and append with first letter of array[2] that is R which will be AlexR
Take first array[0] append with first letter of array[1] along with array[2] which will become AlexSRobert.
Basically the whole idea is when someone enter first name, middle name & last name I should be able to make combination and guess email ids. For example- Juan F. Nathaniel the array form will be like ['Juan', 'F', 'Nathaniel']
I want the combination of first, middle and last name like jaunn, jnathaniel, jaunfnathaniel
I'm beginner and here is what I've written:
var nameCombination = function(name){
var counting = name.split(" ");
for (var i=0; i<counting.length; i++){
console.log(counting[i] + counting[i+1]);
console.log(counting[i].split("",1) + counting[i+1]);
}
}
nameCombination('Alex Sam Robert');
I'm assuming you needed a function to do this? Here is a function to handle grabbing pieces of each index of the array. I'll leave it up to you to figure out what type of data you need...
var test = function() {
var array = ['Alex', 'Sam', 'Robert'];
var conditions = [{
index: 0,
length: array[0].length
},
{
index: 1,
length: 1
},
{
index: 2,
length: array[2].length
}]
alert(combine(array, conditions));
}
var combine = function(array, conditions) {
var output = "";
for(index in conditions) {
var condition = conditions[index];
var index = condition['index'];
var length = condition['length'];
output += array[index].substring(0, length);
}
return output;
}
test();
You could use an iterative and recursive approach for variable length of parts an their length.
function combine(array) {
function c(part, index) {
array[index].forEach(function (a) {
var p = part.concat(a);
if (p.length === array.length) {
r.push(p.join(''));
return;
}
c(p, index + 1);
});
}
var r = [];
c([], 0);
return r;
}
var input= ['Johann', 'Sebastian', 'Bach'],
array = input.map(function (a) { return ['', a[0], a]; });
result = combine(array);
console.log(result);
This problem can be solved using recursive approach.
var combinations = function(names, i, n){
if(i == n){
return [];
}
last_names = combinations(names, i + 1, n);
name_combinations = last_names.map(function(last_name){
return [
last_name,
names[i] + last_name,
names[i] + last_name[0],
names[i][0] + last_name,
names[i][0] + last_name[0]
]
});
name_combinations = [].concat.apply([], name_combinations);
name_combinations.push(names[i]);
return name_combinations;
};
var nameCombinations = function(name){
var name_array = name.split(' ');
return Array.from(new Set(combinations(name_array, 0, name_array.length)));
};
nameCombinations('first last');
above function can generate all the desired combinations for a given name.
for example: nameCombinations('first last') will return ["last", "firstlast", "firstl", "flast", "fl", "first"].
Ok without writing out every combination I will do the first few to give you the idea:
assuming
array[0] is the person's first name
array[1] is the person's middle name
array[2] is the person's last name
Firstname+Lastname:
var output = array[0] + array [2];
Firstname+Middlename:
var output1 = array[0] + array[1];
then then you could display the output using innerHTML:
Javascript:
document.getElementById("output").innerHTML = output + '<br>' + output1;
HTML:
<div id="output"></div>
Keep in mind you would need to keep doing that for the rest of the combinations.
Now for the combinations where you need to get the first letter of the variable you need to use charAt which I found from this stack overflow answer.
You would do the same thing as before, except instead you need to use charAt and do something like so:
Firstname+FirstLetterOfLastName:
var output2 = array[0] + array[2].charAt(0);
And you can output it using the same method as before.
If your still confused leave a comment and I will try and answer your questions.
Related
I have an array which looks like
var arr = ["a|c", "a|e", "x|z"];
for(var x in arr){
var appsplit = x.split("|");
}
If the first value(ex: a) in the elements matches then it should combine the values
Ex: output
ace
xz
Please advice how this approach can be done.
You are testing everyone's reading comprehension with that riddle.
var pairs = {};
var arr = ["a|c", "a|e", "x|z"];
for(var x in arr)
{
var appsplit = arr[x].split("|");
if(pairs[appsplit[0]] !== "undefined")
{
pairs[appsplit[0]] = pairs[appsplit[0]] + appsplit[1];
}
else
{
pairs[appsplit[0]] = appsplit[1];
}
}
var matches = [];
for(var x in pairs)
{
matches.push(x + pairs[x]);
}
console.log(matches);
We need to map out the arr elements in this object called pairs. The first value in your split would be the key and the second value is appended (or assigned if it's the first match to the key)
You made an error of splitting x, but you are only splitting the index of the element, not the actual value of the element. arr[x] is the actual value, where x specifies the index in the array.
After we've gone through your arr, we can now merge the key with the values. Your output is contained in matches where the key in each pair is prepended to the value of the key's pair.
Some simple code that would to the trick here.
var arr = ["a|c", "a|e", "x|z", "c|b", "z|e", "c|a"];
var resultObj = {};
arr.forEach(function(element, index){
var array = element.split('|');
if(array.length!==2){
console.log("skipping, invalid input data", element);
} else {
var firstLetter = array[0];
var secondLetter = array[1];
if(resultObj[firstLetter]){
resultObj[firstLetter].push(secondLetter);
} else {
resultObj[firstLetter]=[secondLetter];
}
}
});
Object.keys(resultObj).forEach(function(key){
console.log(key + "," + resultObj[key]);
});
You can use .reduce(), Set to not accumulate duplicate values, .some() to check if previous array contains value in current array, .map(), Array.from() and .join() to convert array to string
var arr = ["a|c", "a|e", "x|z"];
var res = arr.reduce(function(a, b) {
var curr = b.split("|");
var set = new Set;
for (let prop of curr) set.add(prop);
if (!a.length) {
a.push(set)
} else {
for (prop of a) {
if (curr.some(function(el) {
return prop.has(el)
})) {
for (el of curr) {
prop.add(el)
}
} else {
for (let prop of curr) set.add(prop);
a.push(set)
}
}
}
return a
}, []).map(function(m) {
return Array.from([...m], function(el) {
return el
}).join("")
});
console.log(res);
I feel like this can be done more elegantly, but I didn't have time to streamline it. :) The below code will do what you want, though:
var aStartArray = **ARRAY_VALUE_HERE**;
var aSplitResultStrings = [];
// step through each element in the array
for (var i = 0, iSALength = aStartArray.length; i < iSALength; i++) {
// split the values for the current array element
var aSplitVal = aStartArray[i].split("|");
var bStringDoesNotExist = true;
// loop through the "result strings" array
for (var j = 0, iSRSLength = aSplitResultStrings.length; j < iSRSLength; j++) {
// if the first letter from the array element = the first letter of the current "result string" . . .
if (aSplitResultStrings[j].charAt(0) === aSplitVal[0]) {
// append the second letter of the array value to the current result string
aSplitResultStrings[j] = aSplitResultStrings[j] + aSplitVal[1];
// indicate that a match has been found and exit the "result string" loop
bStringDoesNotExist = false;
break;
}
}
// if there are no result strings that start with the first letter of the array value . . .
if (bStringDoesNotExist) {
// concatenate the two values in the current array value and add them as a new "result string"
aSplitResultStrings.push(aSplitVal[0] + aSplitVal[1]);
}
}
Using these arrays, the results are:
aStartArray = ["a|c", "a|e", "x|z"] //results in:
aSplitResultStrings = ["ace", "xz"]
aStartArray = ["a|b", "a|c", "a|d", "a|e", "x|y", "x|z"] //results in:
aSplitResultStrings = ["abcde", "xyz"]
aStartArray = ["a|b", "d|e", "d|f", "x|y", "g|h", "g|i", "m|n", "g|j", "a|c", "x|z"] //results in:
aSplitResultStrings = ["abc", "def", "xyz", "ghij", "mn"]
As I said, this could be more elegant (for example, you could probably use Map to make iterating through the "result strings" easier), but this makes the steps pretty clear and should get you going down the right path towards a final solution.
I have string like the following:
11222233344444445666
What I would like to do is output the number followed the times it was displayed:
112433475163
Question is, I want this to be efficient. I can store this in an object as the following:
1: { id: 1, displayed: 2},
2: { id: 2, displayed: 1},
3: { id: 3, displayed: 2},
etc.
I can access this object and increment displayed.
My issues is, there is no guarantee in the order. I would like to store the keys in the order they are in the string. How do I accomplish the importance of the order in the object?
This is a proposal for run length coding with an array which holds infomation about one charcter and the count of it:
{
"char": "1",
"count": 2
},
var string = "11222233344444445666",
array = function () {
var r = [], o = {};
string.split('').forEach(function (a, i, aa) {
if (a !== aa[i - 1]) {
o[a] = { char: a, count: 0 };
r.push(o[a]);
}
o[a].count++;
});
return r;
}(string);
document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');
Quick solution with for loop:
var str = "7771122229933344444445666",
obj = {},
len = str.length,
val = null,
count_str = "",
key = "";
for (var i = 0; i < len; i++) {
val = str[i], key = 'k' + val;
if (!obj[key]) {
obj[key] = {'id': val, 'displayed': 1};
} else {
obj[key].displayed++;
}
}
for (var p in obj) {
count_str += obj[p]['id'] + obj[p]['displayed'];
}
console.log(count_str); // "7312249233475163"
because you have such a small set of distinct numbers, I seen no reason why you can't use a array (yeah it's not super ideal memorywise if you skip values and it becomes sparse, but for such a small subset it won't affect you enough to worry of it). Then you can use (number-1) as the index and increment that number as needed.
var counts = [];
var str = "11222233344444445666";
for(var i in str){
var index = parseInt(str[i])-1
counts[index] = (counts[index]||0)+1;
}
for(var i in counts){
var which = 1+parseInt(i);
var count = counts[i];
console.log("# of " + which +"'s: "+count);
}
https://jsfiddle.net/ga0fqpqn/
note: You shouldn't need the parseInt(i)... just +i should work but I think jsfiddle has a bug with it about it defaulting i to handle like a string.
You could store an additional array with the order of the numbers, which you only append to if the object doesn't yet contain the given number. Then once you're done counting, iterate through that array and output the number and the count from the lookup dictionary.
var chars = "1234576123452345".split("");
var order = [];
var hash = {};
chars.forEach(function(char) {
if (!hash[char]) {
hash[char] = 1;
order.push(char);
} else {
hash[char]++;
}
});
console.log(order.map(function(char) {
return char + hash[char];
}).join(""));
// "12233343537161"
I have an object. I want to loop through one of it's properties: itself an array of arrays which contain values. For every one of those values, I want to output an array containing a representative value from each of the child arrays, such that every possible combination of values will be output. Where there are more than one value in a child array, a max of 1 value at a time should be allowed. It's at this point that I think it should 'jump on' to the next one (and do the same for all others) but I'm not sure how. The results should look like this:
RABBIT: GREY, FURRY, BOUNCES, CUTE
RABBIT: WHITE, FURRY, BOUNCES, CUTE
RABBIT: RED, FURRY, BOUNCES, CUTE
RABBIT: GREY, FURRY, SCAMPERS, CUTE
RABBIT: WHITE, FURRY, SCAMPERS, CUTE
RABBIT: RED, FURRY, SCAMPERS, CUTE
The array (and it's child arrays) will have unknown lengths, so I've used the for loop. Here is the code so far:
window.onload = function (){
var myObject = {
name: 'RABBIT',
arrayOfValues : [
['GREY','WHITE','RED'],
['FURRY'],
['BOUNCES', 'SCAMPERS'],
['CUTE']
]
};
var results = [];
for (i=0;i<myObject.arrayOfValues.length;i++){
for (j=0; j<myObject.arrayOfValues[i].length;j++){
if(myObject.arrayOfValues[i].length>1) {
var currentProperty = myObject.arrayOfValues[i][j];
myFunc();
}
else {
var currentProperty = myObject.arrayOfValues[i][0];
myFunc();
};
};
};
function myFunc(){
results = results.concat(currentProperty);
if (results.length == myObject.arrayOfValues.length){
var finalResults = myObject.name + ': ' + results
console.log(finalResults);
};
};
};
PS - The form of the data is not set in stone, I just used an object for convenience.
Thanks, Paul
You can make a recursive function call with an increasing index parameter, as well as a string to which you append the new part of the string and return.
var arrayOfArrays = [
['big', 'red'],
['red', 'yellow', 'blue'],
['dog', 'cat']
];
var strings = [];
function eachStep(string_so_far, array_index) {
if (array_index < arrayOfArrays.length) {
for (var i = 0; i < arrayOfArrays[array_index].length; i++) {
var string_for_this_step = string_so_far + arrayOfArrays[array_index][i] + " ";
var string_returned = eachStep(string_for_this_step, array_index+1);
if (string_returned !== "") {
strings.push(string_returned);
}
}
return "";
} else {
return string_so_far;
}
}
eachStep("", 0);
console.log(strings);
Recursion is the native solution here:
// Object as described by question:
var myObject = {
name: 'RABBIT',
arrayOfValues: [
['GREY', 'WHITE', 'RED'],
['FURRY'],
['BOUNCES', 'SCAMPERS'],
['CUTE']
]
};
function permutations(arrays, current_array, idx, results) {
// Init head and results in case this is the first iteration:
idx = idx || 0;
results = results || [];
current_array = current_array || [];
// If there's nothing more to add:
if (arrays.length == idx) {
results.push(current_array);
return;
}
// Otherwise, iterate current level and concat values, while calling next level:
arrays[idx].forEach(function(subArrayItem) {
permutations(arrays, current_array.concat(subArrayItem), idx + 1, results)
});
return results;
}
The function above will return a set of arrays having all combinations, next is a helper function for printing:
// Helper method to print resulting arrays:
function print(obj) {
var separator = "\n"
var prefix = obj.name + ": ";
// Joins the resulting sets with the prefix, and returns printable string:
return prefix + permutations(obj.arrayOfValues).join(separator + prefix)
}
console.log(print(myObject));
I don't know if I have the terminology right, but I have created the following function:
function myCollection(zip, municipality, info) {
this.myZip = zip;
this.myMuni = municipality;
this.myInfo= info;
}
Then I create the following array and add data to it:
var myArray = new Array();
myArray[0] = new myCollection("1000", "municipality A", "info A");
myArray[1] = new myCollection("2000", "municipality B", "info B");
myArray[2] = new myCollection("2000", "municipality C", "info C");
myArray[3] = new myCollection("3000", "municipality D", "info D");
What I would like to achieve:
search inside myArray where a certain zip code in myCollection occurs
display the rest of the data from myCollection for that zipcode
do the same for all other occurences of that same zipcode within the collection
A search for zip "2000" in the examply above should output:
2000, municipality B, info B
2000, municipality C, info C
My train of thoughts
I thought I'd find the occurences (indexes) where the string occurs and then retrieve the required data like this:
console.log(myArray[i].myInfo);
where i is the index within the array where
myArray[i].myZip
matches "2000".
However, I can't get the indexOf to work to search for a string within the object I created, nor can I retrieve all the other occurences that match the same criteria.
Did I choose the right way to do this to start with?
How should I approach this, if you know jQuery or other external libraries should be avoided?
I hope I'm a bit clear - thank you for your thoughts and advice.
You could use a good old while loop :
function findAll(array, fn) {
var result = [], i = -1;
while (++i < array.length) {
if (fn(array[i]) === true) result.push(array[i]);
}
return result;
}
Usage example :
var a = [{ a: 1 }, { a: 2 }, { a: 3 }];
var result = findAll(a, function (item) {
return item.a !== 2;
});
result; // [{ a: 1 }, { a: 3 }]
You can simply iterate over object:
search = function (arr, keyName, value) {
if (arr && keyName && value) {
var i, j = arr.length;
for (i = 0; i < j; i += 1) {
if (arr[i][keyName] === value) {
return {
index : i,
item : arr[i]
}
}
};
return {}
};
And then:
search(myArray, 'myZip', 2000);
In this case indexOf is current i value, so you can simply do var c = myArray[i]; to get collection, that satisfies your filter criteria. If you want to return more result than first collection found, simply add them sequentially to a new array and return it at the end.
i have data in
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
i want the result as
Name: John
Employee Id: 2
Salary: $8000
Address: London
is it possible with split() function in javascript?
You can do it with String.split() but in this case it's simpler to use String.replace():
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
description = description.replace(/;/g, '\n').replace(/:/g, ': ');
/*
"Name: John
EmployeeID: 2
Salary: $8000
Address: London"
*/
If you want the result as an object, try:
var f = function (str) {
var x = {}, key2label = { EmployeeID: 'Employee Id' };
str.replace(/(.+?):(.+?)(;|$)/g, function (match, key, value) {
key = key2label[key] || key;
x[key] = value;
});
return x;
};
If a simple string is needed, but you still need to replace keys:
var f2 = function (str) {
var key2label = { EmployeeID: 'Employee Id' };
return str.replace(/(.+?):(.+?)(;|$)/g, function (match, key, value, semi) {
key = key2label[key] || key;
return key + ': ' + value + (semi ? '\n' : '');
});
};
If you really didn't mean to replace keys, this will do it:
var f3 = function (str) {
return str.split(':').join(': ').split(';').join('\n');
};
... or use Matt Ball's answer.
With this statement:
var arrDescription = description.split(";");
you will get an array with all the values. For more info on split check the following link.
you can even join them afterwards :
printf(arrDescription.join(" "));
For more info on join check the following link.
Max
You can probable try like this to display.
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
var arr=new Array();
arr=description.split(";");
for(var i=0;i<arr.length;i++)
document.writeln("<h4>"+arr[i]+"</h4>");
Yes.
You first should split on the semicolon ;. Loop through those results, and split each result on each colon :.
You will have to build the result by hand.
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London"; var splitted = description.split(";");
for(var i = 0; i < splitted.length; i++) { document.write(splitted[i] + ""); }