function getAllCombinations(arr) {
var f = function(arr) {
var result = [];
var temp = [];
for (var i = 0; i < arr.length; i++) {
temp = [];
temp.push(arr[i]);
result.push(temp);
for (var j = 0; j < arr.length; j++) {
if (j != i) {
temp = [];
temp.push(arr[i]);
temp.push(arr[j]);
result.push(temp);
for (var k = 0; k < arr.length; k++) {
if (k != i && k != j) {
temp = [];
temp.push(arr[i]);
temp.push(arr[j]);
temp.push(arr[k]);
result.push(temp);
for (var l = 0; l < arr.length; l++) {
if (l != i && l != j && l != k) {
temp = [];
temp.push(arr[i]);
temp.push(arr[j]);
temp.push(arr[k]);
temp.push(arr[l]);
result.push(temp);
}
}
}
}
}
}
}
return result;
}
return f(arr);
}
//call this function
console.log(getAllCombinations(["a", "b", "c", "d"]));
[["a"],["a","b"],["a","b","c"],["a","b","c","d"],["a","b","d"],["a","b","d","c"],["a","c"],["a","c","b"],["a","c","b","d"],["a","c","d"],["a","c","d","b"],["a","d"],["a","d","b"],["a","d","b","c"],["a","d","c"],["a","d","c","b"],["b"],["b","a"],["b","a","c"],["b","a","c","d"],["b","a","d"],["b","a","d","c"],["b","c"],["b","c","a"],["b","c","a","d"],["b","c","d"],["b","c","d","a"],["b","d"],["b","d","a"],["b","d","a","c"],["b","d","c"],["b","d","c","a"],["c"],["c","a"],["c","a","b"],["c","a","b","d"],["c","a","d"],["c","a","d","b"],["c","b"],["c","b","a"],["c","b","a","d"],["c","b","d"],["c","b","d","a"],["c","d"],["c","d","a"],["c","d","a","b"],["c","d","b"],["c","d","b","a"],["d"],["d","a"],["d","a","b"],["d","a","b","c"],["d","a","c"],["d","a","c","b"],["d","b"],["d","b","a"],["d","b","a","c"],["d","b","c"],["d","b","c","a"],["d","c"],["d","c","a"],["d","c","a","b"],["d","c","b"],["d","c","b","a"]]
A total of 64 combinations for a 4 length array.
The function works fine but I need to make this function recursive. The for loops have to be nested based on the length of the array and the push also increased per nested loop.
Really appreciate some advice.
Finally made it recursive !!
Tried to work down on the the original code posted above moving each loop functionality into simple functions.
function getAllCombinations(inputArray) {
var resultArray = [];
var combine = function() {
for (var i in inputArray) {
var temp = [];
var tempResult = [];
for (var j in arguments) {
tempResult.push(inputArray[arguments[j]]);
if (arguments[j] == i) {
temp = false;
} else if (temp) {
temp.push(arguments[j]);
}
}
if (temp) {
temp.push(i);
combine.apply(null, temp);
}
}
if (tempResult.length > 0) {
resultArray.push(tempResult);
}
return resultArray;
};
return combine();
}
See the older version here.
Result produces 64 unique combinations for a 4 dimensional array
console.log(getAllCombinations(["a", "b", "c", "d"]));
[["a","b","c","d"],["a","b","c"],["a","b","d","c"],["a","b","d"],["a","b"],["a","c","b","d"],["a","c","b"],["a","c","d","b"],["a","c","d"],["a","c"],["a","d","b","c"],["a","d","b"],["a","d","c","b"],["a","d","c"],["a","d"],["a"],["b","a","c","d"],["b","a","c"],["b","a","d","c"],["b","a","d"],["b","a"],["b","c","a","d"],["b","c","a"],["b","c","d","a"],["b","c","d"],["b","c"],["b","d","a","c"],["b","d","a"],["b","d","c","a"],["b","d","c"],["b","d"],["b"],["c","a","b","d"],["c","a","b"],["c","a","d","b"],["c","a","d"],["c","a"],["c","b","a","d"],["c","b","a"],["c","b","d","a"],["c","b","d"],["c","b"],["c","d","a","b"],["c","d","a"],["c","d","b","a"],["c","d","b"],["c","d"],["c"],["d","a","b","c"],["d","a","b"],["d","a","c","b"],["d","a","c"],["d","a"],["d","b","a","c"],["d","b","a"],["d","b","c","a"],["d","b","c"],["d","b"],["d","c","a","b"],["d","c","a"],["d","c","b","a"],["d","c","b"],["d","c"],["d"]]
Here is my solution using a subroutine, and closures. Also slice is very useful here.
If you found this helpful, or if you think other people will find this helpful, don't be afraid to upvote.
function getMyCombinations(coll) {
const result = [];
(function search(currentPerm, letters) {
if (letters.length === 0) return result.push(currentPerm);
let trimArray = letters.slice(1);
letters.forEach(letter => search(currentPerm + letter, trimArray));
})('', coll)
return result;
}
console.log(getMyCombinations(["a", "b", "c", "d"]));
I have refactored my original answer to better align with the users request.
function findPerm(array, currentPerm = '', result =[]) {
if (array.length === 0) return result;
let trimArray = array.slice(1);
array.forEach(v => {
let copy = [...result];
let perm = (currentPerm + v).split('');
let res = copy.push(perm);
result = findPerm(trimArray, currentPerm + v, copy);
});
return result;
};
console.log(findPerm(['a', 'b', 'c', 'd']));
An alternative solution, seems getting the desired output :)
console.log(JSON.stringify(getMyCombinations(["a", "b", "c", "d"])))
function getMyCombinations(arry) {
var len = arry.length;
var tempArray = [];
var result = []
var tempCount = 1;
var createCombinations = function(count){
var singleLevelArray = [];
arry.forEach(function(item){
if(count){//1
if(count > 1){
for(var j = 0; j < tempArray.length; j++){
if(tempArray[j].indexOf(item) === -1){
var x = tempArray[j].slice();
x.push(item);
singleLevelArray.push(x);
result.push(x);
}
}
} else {
for(var k = 0; k < len; k++){
if(item.indexOf(arry[k]) === -1){
tempArray.push([item, arry[k]]);
result.push([item, arry[k]]);
}
}
}
} else {
result.push([item]);
}
})
if(singleLevelArray.length){
tempArray = []
tempArray = singleLevelArray;
}
if(tempCount < len){
createCombinations(tempCount++);
}
return result;
}
return createCombinations()
}
I want to get position of dots and commas in an array.
w.wer,ads,
should give something like:
[0] > 1
[1] > 5
[2] > 9
How can this be done with javascript?
function getPositions(regex, str) {
var counts = [], m;
while (m = regex.exec(str)) {
counts.push(regex.lastIndex - m[0].length);
}
return counts;
}
// Usage:
getPositions(/[,.]/g, 'w.wer,ads,'); // => [1,5,9]
Try the following
var getAllIndexesOf = function(str, toFind) {
var all = [];
for (var i = 0; i < str.length; i++) {
if (toFind.indexOf(str[i]) >= 0) {
all.push(i);
}
}
return all;
}
var result = getAllIndexsOf("w.wer,ads,", [".", ","]);
Option 1
Simply loop through each character in the string:
var myString = "w.wer,ads,";
var matchedIndexes = [];
for (var i = 0; i < myString.length; i++) {
if (myString[i] == "," || myString[i] == ".") {
matchedIndexes.push(i);
}
}
Here's a working fiddle.
Option 2
If you wanted to get a bit fancier with it, you could create an object that stores the position and the character at that position:
var myString = "w.wer,ads,";
var matchedIndexes = [];
for (var i = 0; i < myString.length; i++) {
if (myString[i] == "," || myString[i] == ".") {
matchedIndexes.push(new myMatch(myString[i], i));
}
}
function myMatch(position, character) {
this.position = position;
this.character = character;
}
Result:
Here's a working fiddle.
function dotsAndCommas(s) {
var rv = [];
for (var i = 0; i < s.length; ++i) {
if (s[i] === '.' || s[i] === ',') rv.push(i);
}
return rv;
}
Basically, just do it. There's no shortcut way I can think of to do it with a regex.
Probably not ideal, but as a thought experiment, here is a way to do it with built-in javascript functions (no explicit loops):
var pos = mystr.split(/[,.]/).slice(0,-1).map(function(val, i, a) { return a.slice(0, i+1).join('').length+i; });
Demo: http://jsfiddle.net/jtbowden/hHSB2/
To get rid of the nested .slice() which is O(n^2):
var pos = mystr.split(/[,.]/).slice(0,-1).map(function(val, i, a) { return a[i] = val.length+(a[i-1]||-1)+1; });
Demo: http://jsfiddle.net/jtbowden/hHSB2/1/
And, yes, it is still ugly and pointless.
Yet another almost one-liner:
var q = [];
[].forEach.call('w.wer,ads,', function(v, i) { /[,.]/.test(v) ? q.push(i) : 0 } );
// q == [1,5,9]
I would loop through the string and check each character like so:
var s = "w.wer,ads,";
var arr = new Array();
for( var i = 0; i < s.length; i++ ) {
if( s.charAt(i) == "." || s.charAt(i) == "," )
arr.push(i);
}
for( var i = 0; i < arr.length; i++ ) {
document.write( arr[i] );
}
Since there're 5 solutions already, I'll write my almost one-liner.
function dotsAndCommasPositions(str) {
var i = -1;
return str.split(/[.,]/).slice(0, -1).map(function(s){ return i += s.length + 1; });
};
You can create a function that loops through all the characters and saves the index of . and ,.
function getPositionsOfDotsCommas(str) {
var result = [];
for (var i = 0; i < str.length; i++) {
if (str[i] === '.' || str[i] === ',') {
result.push(i);
}
}
return result;
}
I have a SummaryData array as shown
var summaryData = [[0,100.34],[1,102.31],[2,131.08],[3,147.94],[4,172.55],[5,181.05],[6,180.08]];
My question is:
Is it possible to find out what the position of a value is?
(For example, how can I know where 147.94 is?) (I am expecting "3")
Update:
A more prototype-y way:
var result = summaryData.detect(function(item) { return item[1] === 147.94; });
alert(result[0]);
Or:
function getKey(arr, value) {
var key = null,
item;
for (var i = 0; i < arr.length && !key; i++) {
item = arr[i];
if (item[1] === value) {
key = i;
}
}
return key;
}
Usage:
var n = getKey(summaryData, 147.94); // returns 3.
At the risk of doing your homework for you...
var summaryData = [[0,100.34],[1,102.31],[2,131.08],[3,147.94],[4,172.55],[5,181.05],[6,180.08]];
function findPosition(value, dataArray) {
var a;
for (var i=0, iLen=dataArray.length; i<iLen; i++) {
a = dataArray[i];
for (var j=0, jLen=a.length; j<jLen; j++){
if (value == a[j]) {
return i + ',' + j;
}
}
}
}
alert(findPosition(131.08, summaryData)); // 2,1
The above returns the position of the first match.
Edit
I see now that you don't need to iterate over the second array, just look at the second value, so:
function findPosition(value, dataArray) {
var a;
for (var i=0, iLen=dataArray.length; i<iLen; i++) {
a = dataArray[i];
if (value == a[1]) {
return a[0];
}
}
}
alert(findPosition(131.08, summaryData)); //2
Or if the data format is always as specified and there may be thousands of values, then it may be much faster to do:
function findPosition(value, dataArray) {
var re = new RegExp('[^,],' + value);
var m = dataArray.join().match(re);
return m && m[0].replace(/,.*/,'');
// Or
// return m && m[0].split(',')[0];
}
function getPosition(candidate) {
var i = summaryData.length;
while (i) {
i -= 1;
if (summaryData[i][1] === candidate) {
return summaryData[i][0];
}
}
}