Remove duplicate string from Array - javascript

I have the following dynamically generated arrays:
,<div id="layer0" style="left: 470px; top: 286px;">Some Text</div>
,<div id="layer0" style="font-size: 68px; left: 70px; top: 286px; ">SomeText</div>
,<div id="layer1" style="font-size: 18px; left: 60px; top: 286px; ">SomeText</div>
,<div id="layer2" style="font-size: 18px; left: 50px; top: 286px; ">SomeText</div>
The first 2 entries are not exactly duplicates but have the same id="layer0". The second one is different because it has a CSS font-size propriety.
How can I remove the first any from this array that has a duplicate id but may differ in the exact form?
The arrays are combined together trough:
var allcode = $.merge([oldarray],[newarray])
Where in oldarray are some duplicates I need to get rid of.
Thank you.

I think you'd be ahead to more carefully combine the arrays, rather than mash them together and clean up later.
function matchId(htmlstring){
var match = htmlstring.match( new RegExp(/id=\"([^\"]+)\"/i) );
if (match && match[1]) {
return match[1];
}
return '';
}
for (var j=0; j < oldarray.length; j++) {
var exists = false;
for (var k=0; k < newarray.length; k++) {
var newId = matchId(newarray[k]);
var oldId = matchId(oldarray[j]);
if (newId == oldId) {
// element already exists.
exists=true;
break;
}
}
if (!exists) {
newarray.push( oldarray[j] );
}
}

Related

Ignore Whitespace-only Array Elements

I have many comma separated strings, each of which consists of a list of tags, and I want to style each tag inside a box (see here).
I converted each comma separated string ("p") into an array, then wrapped <span> tags around each value in the array, so I could style it with CSS, which worked great.
But whitespace strings are also getting wrapped in span tags which I do not want, I want to ignore those (or hide them).
How do I ignore those occurrences of "p" which contain only whitespace? The answers here and here but didn't work for me.
HTML:
<p>Skill 1, Skill 2, Skill 3</p>
<p>Skill 1</p>
<p> </p>
Javascript:
$("p").each(function() {
var words = $(this).text().split(", ");
var total = words.length;
$(this).empty();
for (index = 0; index < total; index++) {
$(this).append($("<span class = 'tag' > ").text(words[index]));
}
})
CSS:
.tag {
background-color: lightgray;
padding: 3px;
margin: 3px;
border-radius: 3px;
}
JS Fiddle
Just check to see if the trimmed text is truthy first. Also make sure not to implicitly create global variables, always declare variables with const (or let or var) before using them, otherwise errors will be thrown in strict mode:
if (words[index].trim()) {
$(this).append($("<span class = 'tag' > ").text(words[index]));
}
// Converts comma separated string into tags
function convertToTags(s) {
$(s).each(function() {
var words = $(this).text().split(", ");
var total = words.length;
$(this).empty();
for (let index = 0; index < total; index++) {
if (words[index].trim()) {
$(this).append($("<span class = 'tag' > ").text(words[index]));
}
}
})
}
// Calls the function on document ready
$(document).ready(function() {
convertToTags("p");
});
.tag {
background-color: lightgray;
padding: 3px;
margin: 3px;
border-radius: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>This, is, a, test</p>
<p>This</p>
<p> </p>
You need to apply your function only to the relevant elements.
In the following example I've used this condition:
$(this).text().trim().length > 0
$("p")
.each(function() {
const text = $(this).text().trim();
// This condition will make sure that "empty" p elements won't be affected
if (text.length > 0) {
var words = $(this).text().split(", ");
var total = words.length;
$(this).empty();
for (index = 0; index < total; index++) {
$(this).append($("<span class = 'tag' > ").text(words[index]));
}
}
})
.tag {
background-color: lightgray;
padding: 3px;
margin: 3px;
border-radius: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Skill 1, Skill 2, Skill 3 </p>
<p>Skill 1</p>
<p> </p>
function convertToTags(s) {
$("p").each(function() {
var text = $(this).text();
if(!text.replace(/ /g, '')){
$(this).remove();
return;
}
var words = text.split(", ");
var total = words.length;
$(this).empty();
for (index = 0; index < total; index++) {
$(this).append($("<span class = 'tag' > ").text(words[index]));
}
})
}
Magic lies in the first 2 statements within .each function. Before doing the split, we will check if there is anything else in this paragraph other than whitespace(s).
If not, remove this paragraph and start the next iteration.

How to repeat an html element n number of times using javascript

I'm trying to print an element, in my case an hr tag some number of times according to the length of a word. This code is for a hangman game I'm trying to recreate. I have looked up similar questions and its not quite what I'm lookin for.
This is my javascript code so far.
var words = ['Quaffle', 'Bludger', 'Golden Snitch', 'Time-Turner',
'Pensieve', 'Mirror of Erised'];
function getRandomWord(){
var randomIndex = words[Math.floor(Math.random()* words.length)];
alert(randomIndex);
}
function printDashes(){
var dashes = document.getElementById("dash")
}
getRandomWord()
printDashes()
I'm not sure what to add after retrieving the element. Can someone guide me on how to go about this?
You can also create div's so you can enter letters when the user inputs a character. I've attached an example below.
UPDATE: Added example code to update the dashes with letters based on word
var elem = document.getElementById('container');
var guess = document.getElementById('guess');
var word = "Hello";
// draw empty dashes
var drawDashes = function(numberOfDashes) {
for (var i = 0; i < numberOfDashes; i++) {
var el = document.createElement('div');
el.classList = 'dash';
// we draw an empty character inside so that the element
// doesn't adjust height when we update the dash later with a
// letter inside
el.innerHTML = ' ';
elem.appendChild(el);
}
}
// update dash with a letter based on index
var updateDash = function(index, letter) {
elem.children[index].innerHTML = letter;
}
guess.addEventListener('keyup', function(evt) {
// split the word up into characters
var splitWord = word.split('');
// check to see if the letter entered matches any of the
// words characters
for (var i = 0; i < splitWord.length; i++ ) {
// it is important we convert them to lowercase or
// else we might get a mismatch because of case-sensitivity
if (evt.key.toLowerCase() === splitWord[i].toLowerCase()) {
// update dash with letter based on index
updateDash(i, evt.key.toLowerCase());
}
}
// clear out the value
this.value = '';
});
drawDashes(word.length);
body {
font-family: sans-serif;
}
.dash {
height: 50px;
width: 50px;
margin: 0 10px;
display: inline-block;
border-bottom: 2px solid black;
font-size: 32px;
font-weight: bold;
text-align: center;
}
#guess {
height: 50px;
width: 50px;
padding: 0;
font-size: 32px;
text-align: center;
}
<div id="container"></div>
<h4>Type a letter</h4>
<input id="guess" type="text"/>
Say your word is in some variable named myWord.
Get the length of the word by doing:
var myWordLen = myWord.length;
Then you can create HTML elements using Javascript createElement method and appending child elements, information etc as needed. But since you want as many elements as the length of a word, use a loop. Eg:
for(var i=0; i < myWordLen; i++)
{
var tr1 = document.createElement("hr");
var someEle = document.getElementById("someID");
someEle.appendChild(tr1);
}
What about this way?
myElement.innerHTML = `<...>`.repeat(words.length)

looping through an array of images and setting a div's innerHTML to contain all of them

i am trying to use JS to update my div to with all of the images from an array. what i've got now will update one image - how do i properly loop at add all of them from the array?
playersBox = ['images/char-boy.png', 'images/char-cat-girl.png', 'images/char-horn-girl.png', 'images/char-pink-girl.png', 'images/char-princess-girl.png'];
JS
let playerContainer = document.getElementById('players-container');
for (var i = 0; i < playersBox.length; i++) {
playerContainer.innerHTML = '<img src=\"'+playersBox[i]+'\">';
}
HTML
<div id="players-container">
</div>
CSS
#players-container {
height: 151px;
width: 505px;
background-color: #eee;
margin: 0 auto;
}
You are REdefining the innerHTML in your loop, so you only get the last image as it gets overwritten... Do this:
let playerContainer = document.getElementById('players-container');
playerContainer.innerHTML = "";
for (var i = 0; i < playersBox.length; i++) {
playerContainer.innerHTML += '<img src=\"'+playersBox[i]+'\">';
}
Note the += this will append to the HTML instead of replace.
You need to do playerContainer.innerHTML += '<img src=\"'+playersBox[i]+'\">'; with += operator:
var playersBox = ['images/char-boy.png', 'images/char-cat-girl.png', 'images/char-horn-girl.png', 'images/char-pink-girl.png', 'images/char-princess-girl.png'];
let playerContainer = document.getElementById('players-container');
for (var i = 0; i < playersBox.length; i++) {
playerContainer.innerHTML += '<img src=\"'+playersBox[i]+'\">';
}
#players-container {
height: 151px;
width: 505px;
background-color: #eee;
margin: 0 auto;
}
<div id="players-container">
</div>
You need to use += when updating the innerHTML of the div, which will append more HTML instead of replacing the old HTML with the new HTML.
let playerContainer = document.getElementById('players-container');
for (var i = 0; i < playersBox.length; i++) {
playerContainer.innerHTML += '<img src=\"'+playersBox[i]+'\">';
}
Demo:
<div id="players-container">
</div>
<script>
let playersBox = ['https://www.w3schools.com/w3css/img_lights.jpg', 'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&h=350', 'https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg', 'https://images.pexels.com/photos/658687/pexels-photo-658687.jpeg?auto=compress&cs=tinysrgb&h=350', 'https://i.gifer.com/PL7r.gif'];
let playerContainer = document.getElementById('players-container');
for (var i = 0; i < playersBox.length; i++) {
playerContainer.innerHTML += '<img width="50" height="50" src=\"'+playersBox[i]+' \"><p/>';
}
</script>
With each iteration of your loop, you are overwriting the HTML inside playerContainer. This loop concatenates the images:
let playerContainer = document.getElementById('players-container');
let html = "";
for (var i = 0; i < playersBox.length; i++) {
html += '<img src=\"'+playersBox[i]+'\">';
}
playerContainer.innerHTML = html;
As you are using innerHTML inside of loop and you are not concatenating so, you could also use map() function of array to get required result. Using map you can first create your image tag array and then after at last you can directly put into innerHTML.
DEMO
const playersBox = ['images/char-boy.png', 'images/char-cat-girl.png', 'images/char-horn-girl.png', 'images/char-pink-girl.png', 'images/char-princess-girl.png'];
let playerContainer = document.getElementById('players-container');
playerContainer.innerHTML = playersBox.map(v=>`<img src=${v} />`).join('<br>');
#players-container {
height: 151px;
width: 505px;
background-color: #eee;
margin: 0 auto;
}
<div id="players-container">
</div>

How to properly clone a branch in a DOM structure using Javascript and removing the last node

I have two divs, one for left side and one for right side.
On the left one I appended 5 different images. I need to clone those 5 to the right one, append them to the right one and delete the last node.
For the left one:
var LS = document.getElementById("left");
var number = 5;
while(number > 0)
{
var theImage = document.createElement("img");
LS.appendChild(theImage);
number--;
}
For the right side:
var RS = document.getElementById("right");
var leftImages = LS.cloneNode(true);
RS.appendChild(leftImages);
while(RS.lastChild!=null)
{
var noviCh = RS.lastChild;
}
RS.removeChild(noviCh);
Code doesn't work. Anyone has idea why?
Instead of adding all the images and then removing one, how about just not adding the last one in the first place?
var LS = document.getElementById("left");
for (var i = 0; i < 5; i += 1) {
var theImage = document.createElement("img");
LS.appendChild(theImage);
}
var RS = document.getElementById("right");
var imgs = LS.getElementsByTagName('img');
for (var i = 0; i < imgs.length - 1; i += 1) {
RS.appendChild(imgs[i].cloneNode(true));
}
#left {
background-color: yellow;
}
#right {
background-color: green;
}
img {
width: 100px;
height: 100px;
background-color: red;
}
<div id="left"></div>
<div id="right"></div>
var LS = document.getElementById("left");
for ( var number = 5; number > 0; number--)
{
LS.appendChild(document.createElement("img"));
}
and
var RS = document.getElementById("right");
while( LS.lastChild )
{
RS.appendChild( LS.lastChild.cloneNode(true) );
LS.removeChild( LS.lastChild );
}

Creating div's from an array

So I am creating a platformer game with jQuery, JavaScript and HTML. I would like to make every level with an array containing numbers. Each number will then be a "block" of the platformer.
For instance:
var level = ["10101"];
Would create 3 different blocks, each of with are seperated by a blank space.
However, in the platformer, every number of the array caracterises the height, so a 2 would be on top of a 1.
See where I'm going?
Thing is, I have no clue how to append a series of div's to the game so that they have diffrent x position to fill the .game div.
Plus, I added a for loop with a variable named j, however, if I take out anything to do with jand the loop itself, the code doesn't work... why?
I have the code on CodePen, but here is what I have done so far anyway (for some reason it doesn't work on stackoverflow):
IMPORTANT: The CodePen uses SCSS, not CSS, I converted the code using SassMeister !
$(document).ready(function() {
var level = ["1112222111111111111"];
for (var i = 0; i < level.length; i++) {
for (var j = 0; j < level[i].length; j++) {
var n = level[i][j];
var s = $(".block").width();
if (n === "1") {
$("<div>", {
"class": "block pos1" //or any other logic applied to your borad
}).appendTo(".game");
$(this).css("left", i * s + "px")
}
if (n === "2") {
$("<div>", {
"class": "block pos2" //or any other logic applied to your borad
}).appendTo(".game");
}
}
}
});
.game {
position: absolute;
left: calc((100% - 800px)/2);
height: 500px;
width: 800px;
border: 2px solid black;
}
.block {
background-color: black;
height: 50px;
width: 50px;
position: absolute;
border: 0.5px solid red;
}
.pos1 {
bottom: 0;
}
.pos2 {
bottom: 50px;
}
.pos3 {
bottom: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="game">
<!-- examples of positions -->
<!--<div class = "block pos1"></div>
<div class = "block pos2"></div>
<div class = "block pos5"></div>
<div class = "block pos4"></div>-->
</div>
Please Help!
Thank you! Tell me if I need to be more clear!
To append the element using jQuery, replace
for(var each in level) {
level[each].$(".game").append("<div class = 'block pos3'></div>");
}
with
for(var i = 0, length = level.length; i < length; i++){
$("<div>", {
"class": "block pos" + level[i] //or any other logic applied to your borad
}).appendTo(".game");
}
Also, for(var i in obj) is for iterating through the properties of an object, the sequence of the element being iterated is not guaranteed. For arrays, you should use for(var i = 0; i < x; i++) Javascript for loop

Categories