Related
I have 9 strings "a", "b", "c", "d", "e", "f", "g", "h", "i" in a JavaScript array.
const arr = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
I am printing the value of arr using JavaScript alert box.
but, if I use arr.join(" ") it is expected like:
a b c d e f g h i
but, I want to change the line for every 3rd element.
like:
a b c
d e f
g h i
How can I do this?
You can use a for loop with Array#slice.
const arr = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
const parts = [];
for(let i = 0; i < arr.length; i += 3){
parts.push(arr.slice(i, i + 3).join(' '));
}
console.log(parts.join('\n'));
This is what I use to chunk arrays:
const chunkSize = 3;
array
.map((_, i) =>
i % itemsPerPage
? undefined
: items.slice(
i,
Math.floor(i / chunkSize) * chunkSize + chunkSize
)
)
.filter(($) => !!$);
So chunk it up and use:
chunkedArray.map((array) => array.join(" ")).join("\n");
The .map used changes all the arrays inside to a b c and then join all of them with a newline character :)
You can also do that with join by using template literal. e.g:
var arr = ["P613221", "W123456", "ew76879", "GDG767"]
var stringWithQuotes = `'${arr.join(`', '`)}'`
console.log({
stringWithQuotes,
query: `SELECT * FROM users WHERE id IN (${stringWithQuotes})`
})
output:
"P613221', 'W123456', 'ew76879', 'GDG767"
suppose we have this array :
let a = ["a", "b", "c"]
I need some combination like below:
[["a"], ["b"], ["c"], ["a", "b"], ["a", "c"], ["b", "c"], ["b", "a"], ["c", "a"], ["c","b"], ["a", "b", "c"], ...]
const a = ["a", "b", "c"];
function perm(xs) {
let ret = [];
for (let i = 0; i < xs.length; i = i + 1) {
let rest = perm(xs.slice(0, i).concat(xs.slice(i + 1)));
if (!rest.length) {
ret.push([xs[i]])
} else {
for (let j = 0; j < rest.length; j = j + 1) {
ret.push([xs[i]].concat(rest[j]))
}
}
}
return ret;
}
console.log(perm(a));
feel free to edit this question and if this is a similar question pls duplicate the question .strong text
after searching a while, I foundout there is a function :
function combination(A, comb = [], result = [comb]) {
for (var i = 0; i < A.length; i++)
result = result.concat(combination(A.slice(0, i).concat(A.slice(i + 1)), comb.concat(A[i])));
return result;
}
console.log(combination(["q", "a", "w"]))
and you can delete the first index with .slice(1, array.length)
Suppose I have arrays parent and child. I want to check if a child exists inside a parent array. The ordering matters.
Example:
parent = ["x", "a", "b", "c", "d", "e", "f", "g"]
child = ["a", "b", "c"]
//returns true
Example:
When parent has a different order:
parent = ["x", "g", "b", "c", "d", "e", "f", "a"]
child = ["a", "b", "c"]
//It should return false
How would I achieve this in Javascript?
Edit: I have tried this How to check if an array contains another array? but it did not work for my case
You can run a loop for child and change the index accordingly. You can also use a match variable to detect change in the sequence.
RETURN TRUE
var parent = ["x", "a", "b", "c", "d", "e", "f", "g"]
var child = ["a", "b", "c"];
var initIndex = parent.indexOf(child[0]);
var match = true;
for(var i=1; i<child.length; i++){
var varIndex = parent.indexOf(child[i]);
if( varIndex === initIndex+1){
initIndex = varIndex;
continue;
}
match = false;
}
console.log(match);
RETURN FALSE
var parent = ["x", "g", "b", "c", "d", "e", "f", "a"]
var child = ["a", "b", "c"];
var initIndex = parent.indexOf(child[0]);
var match = true;
for(var i=1; i<child.length; i++){
var varIndex = parent.indexOf(child[i]);
if( varIndex === initIndex+1){
initIndex = varIndex;
continue;
}
match = false;
}
//return false
console.log(match);
USING STRING OPERATION
You can also convert the array to string to avoid those loop:
var parent = ["x", "g", "b", "c", "d", "e", "f", "a"]
var child = ["a", "b", "c"]
var parentStr = parent.toString();
var match = parentStr.indexOf(child.toString()) !== -1;
//return false
console.log(match);
parent = ["x", "a", "b", "c", "d", "e", "f", "g"]
child = ["a", "b", "c"]
parentStr = parent.toString();
match = parentStr.indexOf(child.toString()) !== -1;
//return true
console.log(match);
Convert the array to string by using JSON.stringify() and remove the square brackets from child string.
Now check the indexOf child in parent to check if it contains the child.
let parent = ["x", "a", "b", "c", "d", "e", "f", "g"];
let child = ["a", "b", "c"];
var parStr = JSON.stringify(parent);
var chldStr = JSON.stringify(child).replace('[', '').replace(']', '')
console.log(parStr.indexOf(chldStr) !== -1);
I wrote a function for this a while back that takes some paramenters:
Array.prototype.containsArray = function (child, orderSensitivity, caseSensitivity, typeSensitivity) {
var self = this;
if (orderSensitivity) return orderSensitiveComparer();
else return orderInsensitiveComparer();
function orderSensitiveComparer() {
var resultArry = [],
placeholder = 0;
if (child.length > self.length) return false;
for (var i = 0; i < child.length; i++) {
for (var k = placeholder; k < self.length; k++) {
if (equalityComparer(self[k], child[i])) {
resultArry.push(true);
if (resultArry.length === child.length) return true;
placeholder = k + 1;
break;
}
else resultArry = [];
}
}
return false;
}
function orderInsensitiveComparer() {
for (var i = 0; i < child.length; i++) {
var childHasParentElement = false;
for (var k = 0; k < self.length; k++) {
if (equalityComparer(child[i], self[k])) {
childHasParentElement = true;
break;
}
}
if (!childHasParentElement) return false;
}
return true;
}
function equalityComparer(a, b) {
if (caseSensitivity && typeSensitivity) return caseSensitiveEq(a, b) && typeSensitiveEq(a, b);
else if (!caseSensitivity && typeSensitivity) return caseInsensitiveEq(a, b) && typeSensitiveEq(a, b);
else if (caseSensitivity && !typeSensitivity) return caseSensitiveEq(a, b) && typeInsensitiveEq(a, b);
else if (!caseSensitivity && !typeSensitivity) return caseInsensitiveEq(a, b) && typeInsensitiveEq(a, b);
else throw "Unknown set of parameters";
function caseSensitiveEq(a, b) {
return a == b;
}
function caseInsensitiveEq(a, b) {
return (a + "").toLowerCase() == (b + "").toLowerCase();
}
function typeSensitiveEq(a, b) {
return typeof(a) === typeof(b);
}
function typeInsensitiveEq(a, b) {
return true;
}
}
}
var parent = [1, 2, 3, "a", "b", "c"];
var child = [1, 2, 3];
var child2 = ["1", "2", "3"];
var child3 = ["A", "b", "C"];
var child4 = ["a", "b", "c"];
var child5 = ["c", "b", "a"];
// Tests:
console.log(parent.containsArray(parent));
console.log(parent.containsArray(child));
console.log(parent.containsArray(child2));
// parent to child 2, order sensitive, not case, not type. => true.
console.log(parent.containsArray(child2, true, false, false));
// parent to child 2, order, not case, type. => false. b/c of type.
console.log(parent.containsArray(child2, true, false, true));
// parent to child 3, order, not case, type. => true.
console.log(parent.containsArray(child3, true, false, true));
// parent to child 4, order, case and type => true.
console.log(parent.containsArray(child4, true, true, true));
// parent to child 4, not order, case and type. => true.
console.log(parent.containsArray(child4, false, true, true));
// parent to child 5, not order case or type => true.
console.log(parent.containsArray(child5));
I have a simple method for small sized arrays of this problem.
First join the array to a string, see Array/join
Search substring, see String/indexOf
parent = ["x", "a", "b", "c", "d", "e", "f", "g"];
child = ["a", "b", "c"];
function matchSubArray(parent, child) {
parentStr = parent.join('');
childStr = child.join('');
return parentStr.indexOf(childStr) != -1;
}
matchSubArray(parent, child);
var parent = ["x", "g", "b", "c", "d", "e", "f", "a"]
var child = ["a", "b", "c"]
if(parent.join("").search(child.join("")) === -1) {
console.log("Not found");
} else {
console.log("found")
}
I have an array like var aa = ["a","b","c","d","e","f","g","h","i","j","k","l"]; I wanted to remove element which is place on even index. so ouput will be line aa = ["a","c","e","g","i","k"];
I tried in this way
for (var i = 0; aa.length; i = i++) {
if(i%2 == 0){
aa.splice(i,0);
}
};
But it is not working.
Use Array#filter method
var aa = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"];
var res = aa.filter(function(v, i) {
// check the index is odd
return i % 2 == 0;
});
console.log(res);
If you want to update existing array then do it like.
var aa = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"],
// variable for storing delete count
dCount = 0,
// store array length
len = aa.length;
for (var i = 0; i < len; i++) {
// check index is odd
if (i % 2 == 1) {
// remove element based on actual array position
// with use of delete count
aa.splice(i - dCount, 1);
// increment delete count
// you combine the 2 lines as `aa.splice(i - dCount++, 1);`
dCount++;
}
}
console.log(aa);
Another way to iterate for loop in reverse order( from last element to first ).
var aa = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"];
// iterate from last element to first
for (var i = aa.length - 1; i >= 0; i--) {
// remove element if index is odd
if (i % 2 == 1)
aa.splice(i, 1);
}
console.log(aa);
you can remove all the alternate indexes by doing this
var aa = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"];
for (var i = 0; i < aa.length; i++) {
aa.splice(i + 1, 1);
}
console.log(aa);
or if you want to store in a different array you can do like this.
var aa = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"];
var x = [];
for (var i = 0; i < aa.length; i = i + 2) {
x.push(aa[i]);
}
console.log(x);
You can use .filter()
aa = aa.filter((value, index) => !(index%2));
You can use temporary variable like below.
var a = [1,2,3,4,5,6,7,8,9,334,234,234,234,6545,7,567,8]
var temp = [];
for(var i = 0; i<a.length; i++)
if(i % 2 == 1)
temp.push(a[i]);
a = temp;
in Ecmascript 6,
var aa = ["a","b","c","d","e","f","g","h","i","j","k","l"];
var bb = aa.filter((item,index,arr)=>(arr.splice(index,1)));
console.log(bb);
const aa = ["a","b","c","d","e","f","g","h","i","j","k","l"];
let bb = aa.filter((items, idx) => idx % 2 !== 0)
I read here that splice has O(N) time complexity. Don't use it in a loop!
A simple alternative for removing odd indexes in place:
for (let idx = 0; idx < aa.length; idx += 2)
aa[idx >> 1] = aa[idx];
aa.length = (aa.length + 1) >> 1;
I use x >> 1 as a shortcut to Math.floor(x/2).
Hi everyone Can't figure out how can I take element from array in a random way and without repeating. Here is my code:
var letters = [ "A", "A", "B", "B", "C", "C", "D", "D", "E", "E",
"F", "F", "G", "G", "H", "H", "I", "I", "J", "J" ],
cards = document.getElementsByClassName( "cards" ),
cardBoxes = document.getElementsByClassName( "card-boxes" );
//generate random number
function randomNum( nums ) {
return Math.floor( Math.random() * nums.length );
}
//hide letter behind card in random way
function hideLetter() {
for ( var i = cards.length - 1; i >= 0; i-- ) {
var randomLetter = letters[ randomNum(letters) ];
cards[i].textContent = randomLetter;
};
}
hideLetter();
I take element in a random way, but Math.random repeating themselves. I think I have to write some sort of if statment, which will be detect if element was taken two times, but cant figure how to do it. Looking for advice. Thanks.
Here Codepen of problem http://codepen.io/Kuzyo/pen/vdlai
The sure way is to remove element from the array after it was used. This way it will never be repeated
randomise your array, then walk through the randomised array. This has the benefit of the usual "remove elements while using random indices", while keeping the sequence around in case you need a repeat operation that relies on the same random sorting:
function randomize(array) {
var copy = array.slice(),
random = [],
element, pos;
while(copy.length>0) {
pos = (Math.random()*copy.length) | 0; // bit operation forces 32-bit int
subarray = copy.splice(pos, 1);
random.push(subarray[0]);
}
return random;
}
var letters = [ "A", "A", "B", "B", "C", "C", "D", "D", "E", "E",
"F", "F", "G", "G", "H", "H", "I", "I", "J", "J" ],
randomLetters = randomize(letters);
randomLetters.forEach(function(letter) {
// create a card for this letter
});
// do we need it again, in a new random fashion?
// then we can simply call this:
randomLetters = randomize(letters);
Here is my version, with a generator. The function returned by makeRandomGenerator will return random, non-repeating members of inputArray. Once all elements have been used, it will return undefined.
function shuffle(array) {
return array.sort(function() {
return Math.random() > 0.5 ? 1 : -1;
});
}
function makeRandomGenerator(inputArr) {
var arr = inputArr.slice(0);
shuffle(arr);
return function() {
return arr.pop();
}
}
to use:
var letterGenerator = makeRandomGenerator(letters);
function hideLetter() {
for ( var i = cards.length - 1; i >= 0; i-- ) {
var randomLetter = letterGenerator();
if (randomLetter === undefined) {
return;
}
cards[i].textContent = randomLetter;
};
}
hideLetter();
Randomize the array and shift off values from the array :
var letters = [ "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F", "G", "G", "H", "H", "I", "I", "J", "J" ],
cards = document.getElementsByClassName( "cards" ),
i = letters.length, j, temp;
while ( --i ) {
j = Math.floor( Math.random() * (i - 1) );
temp = letters[i];
letters[i] = letters[j];
letters[j] = temp;
}
for ( var i = cards.length; i--; ) {
cards[i].innerHTML = letters.shift();
}
FIDDLE