Related
I'm trying to complete this exercise from codewars. The instructions say: " Write a function that looks for an array within a two-dimensional array and returns the index of the first matching element. If there is no match, your function should return -1"
Exemples:
var arrayToSearch = [[1,2],[3,4],[5,6]];
var query = [1,2]; // => 0
query = [5,6]; // => 2
query = [9,2]; // => -1
This is my solution, but it still fails.
var searchArray = function (arrayToSearch, query) {
for(i = 0; i < arrayToSearch.length; i++) {
for (j = 0; j < arrayToSearch[i]; j++) {
if (arrayToSearch[i][j] === query) {
return i;
}
}
}
return -1;
}
I'm not sure what I'm doing wrong, but I think the problem is in the if statement, but I don't know what it is.
Issue in logic.
Your second if condition j < arrayToSearch[i] will always returns false, because you are comparing a number j against an array arrayToSearch[i]. In this case the number j will be compared agaist the first elementin the array arrayToSearch, which makes the function always returns -1.
Corrected Code
var arrayToSearch = [[1, 2], [3, 4], [5, 6]];
var query = [1, 2]; // => 0
// query = [5, 6]; // => 2
// query = [9, 2]; // => -1
var searchArray = function (arrayToSearch, query) {
for (i = 0; i < arrayToSearch.length; i++) {
let isEqual = true;
for (j = 0; j < arrayToSearch[i].length; j++) {
isEqual = isEqual && (arrayToSearch[i][j] === query[j])
}
if (isEqual) {
return i;
}
}
return -1;
}
console.log(searchArray(arrayToSearch, query));
this simple code will work.
var arrayToSearch = [[1,2],[3,4],[5,6]];
var query = [1,2];
var searchArray = function (arrayToSearch, query) {
for (var i = 0; i < arrayToSearch.length; i++) {
if (arrayToSearch[i][0] == query[0] && arrayToSearch[i][1] == query[1]) {
return true;
}
}
return -1;
}
One-liner if you don't mind:
const arrayToSearch = [[1,2],[3,4],[5,6]];
const query1 = [1,2];
const query2 = [3,4];
const query3 = [5,6];
const query4 = [9,2];
const searchArray = (arr, query) => arr.map(e => e.toString()).indexOf(query.toString());
console.log(`[${query1}]:`, searchArray(arrayToSearch, query1));
console.log(`[${query2}]:`, searchArray(arrayToSearch, query2));
console.log(`[${query3}]:`, searchArray(arrayToSearch, query3));
console.log(`[${query4}]:`, searchArray(arrayToSearch, query4));
.as-console-wrapper{min-height: 100%!important; top: 0}
So I can create a whole bunch of empty objects that are independent with my code below. Is there a better way to do this? Or is this the only method?
var array = [];
for (let i = 0; i < 5; i++)
{
array.push("temp" + i);
}
for (let item of array)
{
eval(`${item} = new Object();`);
}
temp0.first = 1;
temp4.last = "last";
for (let item of array)
{
console.log(eval(item));
}
Simply use an object:
var objects = {};
for (let i = 0; i < 5; i++)
{
objects["temp" + i] = {};
}
Accessing with:
objects["temp0"]
or:
objects.temp0
Or if you want to pollute the global namespace you can use:
for (let i = 0; i < 5; i++)
{
window["temp" + i] = {};
}
And access using:
temp0
temp1 //etc.
or:
window["temp0"] //just like above
Array(5).fill({})
// [{},{},{},{},{}]
Array(5).fill("temp").map((x, i) => x + i)
// ["temp0", "temp1", "temp2", "temp3", "temp4"]
Array.from({length: 5}, (_, i) => "temp" + i)
// ["temp0", "temp1", "temp2", "temp3", "temp4"]
[...Array(5).keys()]
// [0, 1, 2, 3, 4]
It's like this:
function makeMadObjects(num){
var a = [];
for(var i=0; i<num; i++){
a.push({});
}
return a;
}
var arrayOfObjects = makeMadObjects(27);
arrayOfObjects[4].someProperty = 'some value';
console.log(arrayOfObjects);
You can use destructuring assignment to assign variable names to objects within an array, or set property names to objects within an array having dynamic .length, then retrieve specific object from array using index of object within array and property name of object where property is a plain object
let n = 5; // `n`: dynamic; e.g.; Math.floor(Math.random() * 100);
let temps = Array.from({length: n}, (_, i) => ({}));
let len = temps.length;
let [temp0, temp1, temp2, temp3, temp4 /* , ..tempN < len */ ] = temps;
console.log(temp0, temp4);
let n = 5 // Math.floor(Math.random() * 100);
let temps = Array.from({length:n}, (_, i) => ({[`temp${i}`]:{}}));
// set, get `temp0` through `tempN`, when needed for application,
// where `N` is less than `n`, e.g.; set, get `temp0`, `temp4`
let {0:{temp0}, 4:{temp4}} = temps;
console.log(temp0, temp4);
I need code that takes an array, counts the number of elements in it and returns a set of arrays, each displaying a different combination of elements. However, the starting element should be the same for each array. Better to explain with a few examples:
var OriginalArray = ['a','b','c']
should return
results: [['a','b','c'], ['a','c','b']]
or for example:
var originalArray = ['a','b','c','d']
should return
[['a','b','c','d'], ['a','b','d', 'c'], ['acbd', 'acdb', 'adbc', 'adcb']]
Again note how the starting element, in this case 'a' should always be the starting element.
You can use Heap's algorithm for permutations and modify it a bit to add to result only if first element is equal to first element of original array.
var arr = ['a', 'b', 'c', 'd']
function generate(data) {
var r = [];
var first = data[0];
function swap(x, y) {
var tmp = data[x];
data[x] = data[y];
data[y] = tmp;
}
function permute(n) {
if (n == 1 && data[0] == first) r.push([].concat(data));
else {
for (var i = 0; i < n; i++) {
permute(n - 1);
swap(n % 2 ? 0 : i, n - 1);
}
}
}
permute(data.length);
return r;
}
console.log(generate(arr))
You have to do a .slice(1) to feed the rest of the array to a permutations function. Then you can use .map() to stick the first item to the front of each array in the result of permutations function.
If you will do this job on large sets and frequently then the performance of the permutations function is important. The following uses a dynamical programming approach and to my knowledge it's the fastest.
function perm(a){
var r = [[a[0]]],
t = [],
s = [];
if (a.length <= 1) return a;
for (var i = 1, la = a.length; i < la; i++){
for (var j = 0, lr = r.length; j < lr; j++){
r[j].push(a[i]);
t.push(r[j]);
for(var k = 1, lrj = r[j].length; k < lrj; k++){
for (var l = 0; l < lrj; l++) s[l] = r[j][(k+l)%lrj];
t[t.length] = s;
s = [];
}
}
r = t;
t = [];
}
return r;
}
var arr = ['a','b','c','d'],
result = perm(arr.slice(1)).map(e => [arr[0]].concat(e));
console.log(JSON.stringify(result));
Hey i have a simple question i cant find an answer,
i´m trying to generate some raw-data for a chart
lets say i have an array like :
[1,0,0,1,2,0]
is there a way to make an array out of it that has nested arrays that represent the count of duplicate entrys ?
[[0,3],[1,2],[2,1]]
here is some code that does the trick, but saves the count as objects
var array = [1,0,0,1,2,0];
var length = array.length;
var objectCounter = {};
for (i = 0; i < length; i++) {
var currentMemboerOfArrayKey = JSON.stringify(array[i]);
var currentMemboerOfArrayValue = array[i];
if (objectCounter[currentMemboerOfArrayKey] === undefined){
objectCounter[currentMemboerOfArrayKey] = 1;
}else{
objectCounter[currentMemboerOfArrayKey]++;
}
}
but objectCounter returns them like
{0:3,1:2,2:1}
but i need it as an array i specified above ?
for any help, thanks in advance
Try
var array = [1, 0, 0, 1, 2, 0];
function counter(array) {
var counter = [],
map = {}, length = array.length;
$.each(array, function (i, val) {
var arr = map[val];
if (!arr) {
map[val] = arr = [val, 0];
counter.push(arr);
}
arr[1] += 1;
})
return counter;
}
console.log(JSON.stringify(counter(array)))
Demo: Fiddle
You can turn your object into an array easily:
var obj = {0:3,1:2,2:1};
var arr = [];
for (var key in obj) {
// optional check against Object.prototype changes
if (obj.hasOwnProperty(key)) {
arr.push([+key, obj[key]]);
}
}
Note: The object keys are strings, so i converted them back to numbers when placed in the array.
Functional way of doing this, with Array.reduce and Array.map
var data = [1,0,0,1,2,0];
var result = data.reduce(function(counts, current) {
counts[current] = current in counts ? counts[current] + 1: 1;
return counts;
}, {});
result = Object.keys(result).map(function(current){
return [parseInt(current), result[current]];
});
console.log(result);
Output
[ [ 0, 3 ], [ 1, 2 ], [ 2, 1 ] ]
Try:
var data = [1,0,0,1,2,0];
var len = data.length;
var ndata = [];
for(var i=0;i<len;i++){
var count = 0;
for(var j=i+1;j<len;j++){
if(data[i] == data[i]){
count ++;
}
}
var a = [];
a.push(data[i]);
a.push(count);
ndata.push(a);
}
console.log(ndata)
DEMO here.
First you need to map the array to an associative object
var arr = [1,0,0,1,2,0];
var obj = {};
for (var i = 0; i < arr.length; i++) {
if (obj[arr[i]] == undefined) {
obj[arr[i]] = 0;
}
obj[arr[i]] += 1;
}
Then you can easily turn that object into a 2d matrix like so:
arr = [];
for (var k in obj) {
arr.push([k, obj[k]]);
}
alert(JSON.stringify(arr));
Your existing object can be turned into an array with a simple for..in loop. Also your existing code that produces that object can be simplified. Encapsulate both parts in a function and you get something like this:
function countArrayValues(array) {
var counter = {},
result = [];
for (var i = 0, len = array.length; i < len; i++)
if (array[i] in counter)
counter[array[i]]++;
else
counter[array[i]] = 1;
for (i in counter)
result.push([+i, counter[i]]);
return result;
}
console.log( countArrayValues([1,0,0,1,2,0]) );
Demo: http://jsfiddle.net/hxRz2/
I have several numbers in an array
var numArr = [1, 3, 5, 9];
I want to cycle through that array and multiply every unique 3 number combination as follows:
1 * 3 * 5 =
1 * 3 * 9 =
1 * 5 * 9 =
3 * 5 * 9 =
Then return an array of all the calculations
var ansArr = [15,27,45,135];
Anyone have an elegant solution? Thanks in advance.
A general-purpose algorithm for generating combinations is as follows:
function combinations(numArr, choose, callback) {
var n = numArr.length;
var c = [];
var inner = function(start, choose_) {
if (choose_ == 0) {
callback(c);
} else {
for (var i = start; i <= n - choose_; ++i) {
c.push(numArr[i]);
inner(i + 1, choose_ - 1);
c.pop();
}
}
}
inner(0, choose);
}
In your case, you might call it like so:
function product(arr) {
p = 1;
for (var i in arr) {
p *= arr[i];
}
return p;
}
var ansArr = [];
combinations(
[1, 3, 5, 7, 9, 11], 3,
function output(arr) {
ansArr.push(product(arr));
});
document.write(ansArr);
...which, for the given input, yields this:
15,21,27,33,35,45,55,63,77,99,105,135,165,189,231,297,315,385,495,693
I think this should work:
var a = [1, 3, 5, 9];
var l = a.length;
var r = [];
for (var i = 0; i < l; ++i) {
for (var j = i + 1; j < l; ++j) {
for (var k = j + 1; k < l; ++k) {
r.push(a[i] * a[j] * a[k]);
}
}
}
Edit
Just for my own edification, I figured out a generic solution that uses loops instead of recursion. It's obvious downside is that it's longer thus slower to load or to read. On the other hand (at least on Firefox on my machine) it runs about twice as fast as the recursive version. However, I'd only recommend it if you're finding combinations for large sets, or finding combinations many times on the same page. Anyway, in case anybody's interested, here's what I came up with.
function combos(superset, size) {
var result = [];
if (superset.length < size) {return result;}
var done = false;
var current_combo, distance_back, new_last_index;
var indexes = [];
var indexes_last = size - 1;
var superset_last = superset.length - 1;
// initialize indexes to start with leftmost combo
for (var i = 0; i < size; ++i) {
indexes[i] = i;
}
while (!done) {
current_combo = [];
for (i = 0; i < size; ++i) {
current_combo.push(superset[indexes[i]]);
}
result.push(current_combo);
if (indexes[indexes_last] == superset_last) {
done = true;
for (i = indexes_last - 1; i > -1 ; --i) {
distance_back = indexes_last - i;
new_last_index = indexes[indexes_last - distance_back] + distance_back + 1;
if (new_last_index <= superset_last) {
indexes[indexes_last] = new_last_index;
done = false;
break;
}
}
if (!done) {
++indexes[indexes_last - distance_back];
--distance_back;
for (; distance_back; --distance_back) {
indexes[indexes_last - distance_back] = indexes[indexes_last - distance_back - 1] + 1;
}
}
}
else {++indexes[indexes_last]}
}
return result;
}
function products(sets) {
var result = [];
var len = sets.length;
var product;
for (var i = 0; i < len; ++i) {
product = 1;
inner_len = sets[i].length;
for (var j = 0; j < inner_len; ++j) {
product *= sets[i][j];
}
result.push(product);
}
return result;
}
console.log(products(combos([1, 3, 5, 7, 9, 11], 3)));
A recursive function to do this when you need to select k numbers among n numbers. Have not tested. Find if there is any bug and rectify it :-)
var result = [];
foo(arr, 0, 1, k, n); // initial call
function foo(arr, s, mul, k, n) {
if (k == 1) {
result.push(mul);
return;
}
var i;
for (i=s; i<=n-k; i++) {
foo(arr, i+1, mul*arr[i], k-1, n-i-1);
}
}
This is a recursive function.
First parameter is array arr.
Second parameter is integer s. Each call calculates values for part of the array starting from index s. Recursively I am increasing s and so array for each call is recursively becoming smaller.
Third parameter is the value that is being calculated recursively and is being passed in the recursive call. When k becomes 1, it gets added in the result array.
k in the size of combination desired. It decreases recursively and when becomes 1, output appended in result array.
n is size of array arr. Actually n = arr.length
var create3Combi = function(array) {
var result = [];
array.map(function(item1, index1) {
array.map(function(item2, index2) {
for (var i = index2 + 1; i < array.length; i++) {
var item3 = array[i];
if (item1 === item2 || item1 === item3 || item2 === item3 || index2 < index1) {
continue;
}
result.push([item1, item2, item3]);
}
});
});
return result;
};
var multiplyCombi = function(array) {
var multiply = function(a, b){
return a * b;
};
var result = array.map(function(item, index) {
return item.reduce(multiply);
});
return result;
}
var numArr = [1, 3, 5, 9];
// create unique 3 number combination
var combi = create3Combi(numArr); //[[1,3,5],[1,3,9],[1,5,9],[3,5,9]]
// multiply every combination
var multiplyResult = multiplyCombi(combi); //[15,27,45,135];
https://github.com/dankogai/js-combinatorics
Found this library. Tested to be working. Below is from the library document:
var Combinatorics = require('js-combinatorics');
var cmb = Combinatorics.combination(['a','b','c','d'], 2);
while(a = cmb.next()) console.log(a);
// ["a", "b"]
// ["a", "c"]
// ["a", "d"]
// ["b", "c"]
// ["b", "d"]
// ["c", "d"]
Using node, you can do this pretty easily using a library. First install bit-twiddle using npm:
npm install bit-twiddle
Then you can use it in your code like this:
//Assume n is the size of the set and k is the size of the combination
var nextCombination = require("bit-twiddle").nextCombination
for(var x=(1<<(k+1))-1; x<1<<n; x=nextCombination(x)) {
console.log(x.toString(2))
}
The variable x is a bit-vector where bit i is set if the ith element is contained in the combination.