Given an array and a length, I want to derive every possible combination of elements (non-repeating) at the specific length.
So given an array of:
arr = ['a','b','c','d']
and a length of 3, I'm after a function that outputs a 2-dimensional array as follows:
result = [
['a','b','c'],
['b','c','a'],
['c','a','b'],
. . . etc.
]
I've tried tackling this and have had a deal of difficulty.
The following code uses a brute-force approach. It generates every permutation of every combination of the desired length. Permutations are checked against a dictionary to avoid repeating them in the result.
function makePermutations(data, length) {
var current = new Array(length), used = new Array(length),
seen = {}, result = [];
function permute(pos) {
if (pos == length) { // Do we have a complete combination?
if (!seen[current]) { // Check whether we've seen it before.
seen[current] = true; // If not, save it.
result.push(current.slice());
}
return;
}
for (var i = 0; i < data.length; ++i) {
if (!used[i]) { // Have we used this element before?
used[i] = true; // If not, insert it and recurse.
current[pos] = data[i];
permute(pos+1);
used[i] = false; // Reset after the recursive call.
}
}
}
permute(0);
return result;
}
var permutations = makePermutations(['a', 'a', 'b', 'b'], 3);
for (var i = 0; i < permutations.length; ++i) {
document.write('['+permutations[i].join(', ')+']<br />');
}
Related
Let's say that I'm doing this because of my homework. I would like to develop some kind of schedule for the week to come (array of 6-7 elements - output result). But I have one problem. I need to figure it out how one element be positioned in the array and also his frequency must be exactly what user input is. Elements must be positioned at different index in the array.
I'm having that kind of input from user (just an example);
var arrayOfElements = ["el1","el2","el3"];
var el1Frequency = 3;
var el2Frequency = 2;
var el3Frequency = 1;
//output array of schedule (this is just an example)
var finaloutPutArray = ["el1","el2","el3","el1","el2","el1"];
Index of elements el1 is 0, 3 and 5, basically, I don't want elements to be repeated like this;
["el1","el1","el2","el3"...];
["el2","el1","el1","el3"];
Can you please give me some ideas on how to solve this problem.
I started like this;
var finalSchedule = [];
var totalDaysPerWeek = 6;
for(var i =0; i < totalDaysPerWeek; i++) {
...
}
This is one pattern, check my working snippet:
var arrayOfElements = ["el1","el2","el3"];
var obj = { el1: 3,
el2: 2,
el3: 1};
// First determine the max recurring of an element, this will be the number of cycles fo your loop
// Check key values
var arr = Object.keys(obj).map(function ( key ) { return obj[key]; });
// Get max value
var max = Math.max.apply( null, arr );
var finalArray = [];
// Iterate from 0 to max val
for(i = 0; i < max; i += 1){
// Iterate on array of elements
for(k = 0; k < arrayOfElements.length; k += 1) {
// If config of recurring
if( obj[arrayOfElements[k]] >= i+1 ) {
// Push into array
finalArray.push(arrayOfElements[k]);
}
}
}
console.log(finalArray);
I am working on this piece of code here where the goal is to create an array of all the values that are duplicated from another array. The resulting array I'd like to have should only enter the duplicated values from the first array once. The catch is I can't use any array functions or methods. This is what I have so far:
var numbers = [8,24,20,5,13,3,1,12,11,24,8,24,20,4,5,23,24,23,21,2,19,3,21,2,14,17,21,5,7,10,20,11,0,5,18,2,13,11,14,3,20,1,23,6,21,10,14,0,15,20];
var results = [];
var tempArr = [];
for (var i = 0; i <= numbers.length; i++) {
if (tempArr[numbers[i]] === undefined) {
tempArr[numbers[i]] = 1;
} else if (results[numbers[i]] === undefined) {
results.push(numbers[i]);
}
}
console.log(tempArr);
console.log(results);
I am getting closer to me desired output… but for some reason the results array continues to contain multiple entries of the values that are duplicated in the numbers array. Where am I going wrong here?
You're basically abusing an array as an object. Try using an object instead to log your values (and give said object a name that represents what it holds), it'll greatly simplify your code:
var numbers = [8,24,20,5,13,3,1,12,11,24,8,24,20,4,5,23,24,23,21,2,19,3,21,2,14,17,21,5,7,10,20,11,0,5,18,2,13,11,14,3,20,1,23,6,21,10,14,0,15,20];
var results = [];
var seenValues = {};
for (var i = 0; i < numbers.length; i++) {
const number = numbers[i];
seenValues[number] = 1 + (seenValues[number] || 0);
// check to see if it's been seen exactly once before,
// so that the duplicated value is only added once:
if (seenValues[number] === 2) results[results.length] = number;
}
//console.log(seenValues);
console.log(results);
I am working on solving an algorithm (do not want to explain my approach, as I am still trying to solve it on my own). However I am having difficulty with a particular part.
function smallestCommons(arr)
{
var rangeArray = [];
var outterArray = [];
var testArray = [];
arr = arr.sort(function(a,b){return a>b});
for(var i=arr[0];i<=arr[1];i++)
{
rangeArray.push(i);
}
for(var j=0;j<rangeArray.length;j++)
{
for(var k=1;k<=100;k++)
{
if(k%rangeArray[j] === 0)
{
outterArray.push([k]);
}
}
}
console.log(outterArray);
}
smallestCommons([1,5]);
The second part of the code I am looping through the items in rangeArray [1,2,3,4,5] and trying to insert all the multiples (from 1 to 100) of EACH index into a DIFFERENT array. But my code currently is pushing EACH individual number which is a multiple into its own array per each digit. I need it to push all the multiples of each index of rangeArray into outer array. So that I end up with a 2D array of all the multiples of rangeArray in different array for every iteration of j.
So for example instead of ending up with
outerArray == [[1],[2],[3]...]
I would end up with all the multiples of 1 (up to 100) into one array and then all the multiples of 2 into another array and so on and so forth so it looks like this.
outerArray == [[1,2,3,4...] [2,4,6,8...] [3,6,9,12...]]
Its very hard to explain, hopefully I have been clear. Thanks.
It's quite impossible to understand your question, but wisely you've described the output you're trying to generate...
Turns out, that's quite simple:
let arr = [];
for(let i = 1; i <= 100; i++) {
let innerArr = [];
for(let j = i; j <= 100; j += i) {
innerArr.push(j);
}
arr.push(innerArr);
}
console.log(arr);
how many elements should be in each multiple array? I guessed 100 but you can adjust that accordingly...
function smallestCommons(arr)
{
var rangeArray = [];
var outterArray = [];
var testArray = [];
arr = arr.sort(function(a,b){return a>b});
for(var i=arr[0];i<=arr[1];i++)
{
rangeArray.push(i);
}
for(var j=0;j<rangeArray.length;j++)
{
for(var k=1;k<=100;k++)
{
if(k%rangeArray[j] === 0)
{
var multipleArray = [];
for(var z=1;z<100;z++) {
multipleArray.push(z*k);
}
outterArray.push(multipleArray);
}
}
}
console.log(outterArray);
}
smallestCommons([1,5]);
I have a javascript array of objects: each object contains key/value pairs. I'm trying to iterate through this array, and delete any object whose value for a particular key (say "Industry") fails to match a given value. Here is my code, for some reason it's not looping through the whole array, and I think it has something to do with the fact that when I delete an item the loop counter is botched somehow:
var industry = 'testing';
var i = 0;
for (i = 0; i < assets_results.length; i++) {
var asset = assets_results[i];
var asset_industry = asset['industry'];
if (industry != asset_industry) { assets_results.splice(i,1); }
}
Any ideas? Thanks in advance.
This is because when you splice one element, the size of array decreases by one. All elements after the splice shift one position to the beginning of the array and fills the space of spliced one. So the code misses one element.Try this code.
var industry = 'testing';
var i = 0;
for (i = 0; i < assets_results.length; i++) {
var asset = assets_results[i];
var asset_industry = asset['industry'];
if (industry != asset_industry) {
assets_results.splice(i,1);
i--;
}
}
This is a common problem when modifying an object while iterating through it. The best way to avoid this problem is, rather than deleting pairs from the existing array if they fail the test, to create a new array and only add pairs if they pass the test.
var industry = 'testing';
var i = 0;
var asset_results_filtered = [];
for (i = 0; i < assets_results.length; i++) {
if (industry == assets_results[i]) {
asset_results_filtered.push(assets_results[i]);
}
}
EDIT: Your code looked a bit illogical — I modified the example to use the variables given.
splice removes an element from an array and resizes it :
var arra = ['A', 'B', 'C', 'D'];
arr.splice(1,2); // -> ['A', 'D'];
Which means that you should not increment i when you splice, because you skip the next element. splicing will make of the i + 2 element the i + 1 element.
var industry = 'testing';
for (var i = 0, max = assets_results.length; i < max; ) { // Accessing a property is expensive.
if (industry != assets_results[i]['industry']) {
assets_results.splice(i,1);
} else {
++i;
}
}
Try this instead:
var industry = 'testing';
var i = assets_results.length - 1;
for (; i > 0; i--) {
var asset = assets_results[i],
asset_industry = asset['industry'];
if (industry != asset_industry) { assets_results.splice(i,1); }
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Array value count javascript
I have an array which contains several duplicates, what I'm trying to achieve is to count how many duplicates each unique string has in this one array.
The array looks something like this
array = ['aa','bb','cc','aa','ss','aa','bb'];
Thus I would like to do something like this
if (xWordOccurrences >= 5) {
// do something
}
But I'm not sure how I would code this.
I was thinking, create an object with each unique string, then loop through the original array, match each string with it's object and increment it's number by 1, then loop over the object to see which words had the most duplicates...
But this seems like an over complexe way to do it.
You can use an object which has keys of the Array's values and do something like this
// count everything
function getCounts(arr) {
var i = arr.length, // var to loop over
obj = {}; // obj to store results
while (i) obj[arr[--i]] = (obj[arr[i]] || 0) + 1; // count occurrences
return obj;
}
// get specific from everything
function getCount(word, arr) {
return getCounts(arr)[word] || 0;
}
getCount('aa', ['aa','bb','cc','aa','ss','aa','bb']);
// 3
If you only ever want to get one, then it'd be more a bit more efficient to use a modified version of getCounts which looks similar to getCount, I'll call it getCount2
function getCount2(word, arr) {
var i = arr.length, // var to loop over
j = 0; // number of hits
while (i) if (arr[--i] === word) ++j; // count occurance
return j;
}
getCount2('aa', ['aa','bb','cc','aa','ss','aa','bb']);
// 3
Try this function:
var countOccurrences = function(arr,value){
var len = arr.length;
var occur = 0;
for(var i=0;i<len;i++){
if(arr[i]===value){
occur++;
}
}
return occur;
}
var count = countOccurrences(['aaa','bbb','ccc','bbb','ddd'],'bbb'); //2
If you want, you can also add this function to the Array prototype:
Array.prototype.countOccurrences = function(value){
var len = this.length;
var occur = 0;
for(var i=0;i<len;i++){
if(this[i]===value){
occur++;
}
}
return occur;
}
How about you build an object with named property?
var array = ['aa','bb','cc','aa','ss','aa','bb'];
var summary = {};
var item = '';
for ( i in array){
item = array[i];
if(summary[item]){
summary[item] += 1;
}
else{
summary[item] = 1;
}
}
console.log( summary );
summary will contain like this
{aa: 3, bb: 2, cc: 1, ss: 1}
which you could then iterate on and then sort them later on if needed.
finally to get your count, you could use this summary['aa']
<script type="text/javascript">
var array = ['aa','bb','cc','aa','ss','aa','bb'];
var myMap = {};
for(i = 0; i < array.length; i++) {
var count = myMap[array[i]];
if(count != null) {
count++;
} else {
count = 1;
}
myMap[array[i]] = count;
}
// at this point in the script, the map now contains each unique array item and a count of its entries
</script>
Hope this solves your problem
var array = ['aa','bb','cc','aa','ss','aa','bb'];
var dups = {};
for (var i = 0, l = array.length; i < l; i++ ) {
dups[array[i]] = [];
}
for (str in dups) {
for (var i = 0, l = array.length; i < l; i++ ) {
if (str === array[i]) {
dups[str].push(str);
}
}
}
for (str in dups) {
console.log(str + ' has ' + (dups[str].length - 1) + ' duplicate(s)');
}
This function may do everything you need.
function countDupStr(arr, specifier) {
var count = {}, total = 0;
arr.forEach(function (v) {
count[v] = (count[v] || 0) + 1;
});
if(typeof specifier !== 'undefined') {
return count[specifier] - 1;
}
Object.keys(count).forEach(function (k) {
total += count[k] - 1;
});
return total;
}
Each value in the array is assigned and incremented to the count object. Whether or not a specifier was passed, the function will return duplicates of that specific string or the total number of duplicates. Note that this particular technique will only work on string-coercible values inside your arrays, as Javascript can only index objects by string.
What this means is that during object assignment, the keys will normalize down to strings and cannot be relied upon for uniqueness. That is to say, this function wouldn't be able to discern the difference between duplicates of 3 and '3'. To give an example, if I were to perform:
var o = {}, t = {};
o[t] = 1;
console.log(o);
The key used in place of t would eventually be t.toString(), thus resulting in the perhaps surprising object of {'[object Object]': 1}. Just something to keep in mind when working with Javascript properties.
I saw this post about it, perhaps it can help:
http://ryanbosinger.com/blog/2011/javascript-count-duplicates-in-an-array/