I am beginner in JavaScript. I have this code:
var imageArray = [];
$(document).on("click", ".showPrv", function () {
$("#dropzone").each(function () {
$(".dz-image-preview").each(function () {
$(".dz-image").each(function () {
imageArray.push($(this).find("img").attr("src"))
});
});
});
console.log(imageArray);
})
This code works fine, but I have a problem with duplicates in my array imageArray. How can you block duplicates from being added to this table?
Try to use the includes() function.
Using it will be:
...
$(".dz-image").each(function () {
if(!imageArray.includes($(this).find("img").attr("src")))
imageArray.push($(this).find("img").attr("src"))
});
...
You can check if the value exists in the imageArray before pushing a new one, somewhat like this:
const imgSrc = $(this).find("img").attr("src");
if(!imageArray.includes(imgSrc)) {
imageArray.push(imgSrc);
}
I would recommend using a Set for this, as it allows for a quick lookups (O(1)) in order to check if the value already exists. Using an array forces you to do .includes() which takes O(n) time.
const imageSet = new Set();
...
const imgSrcAttr = $(this).find("img").attr("src");
if(!imageSet.has(imgSrcAttr)) {
imageSet.add(imgSrcAttr);
}
...
If at some point you need to convert the set to an array, you can simply use the spread-operator:
const imageArr = [...imageSet];
If the element was not found, -1 will be returned. Refer to $.inArray():
// If not in your array then
if($.inArray($(this).find("img").attr("src"), imageArray) === -1){
// Add value to imageArray
imageArray.push($(this).find("img").attr("src"));
}
Example of $.inArray() on JSFiddle for better understanding.
Related
I want to create objects in a foreach loop:
I'm starting from this:
data.forEach(function (el) {
var dynamic_var = new Quill(el['editor']);
dynamic_var.on('text-change', logHtmlContent);})
But, dynamic_var is 'overwritten', and I want to remain unique.
I check some html elements, and for each one that I found I want to create a new Object, and execute the Object methods.
In my case the variable get a new object per each iteration, is not a new variable.
Is this what you were looking for?
var quillValueContainer = {};
// ...
data.forEach(function(el) {
quillValueContainer[el] = new Quill(el['editor']);
quillValueContainer[el].on('text-change', logHtmlContent);
});
This will only work if el is a string, or number. Seeing how you are using it like this: el['editor'], makes me thing it's an Object, in which case, you can instead use the indices of the elements.
var quillValueContainer = {}; // [] should also work for indexes
// ...
data.forEach(function(el, index) {
quillValueContainer[index] = new Quill(el['editor']);
quillValueContainer[index].on('text-change', logHtmlContent);
});
Also, I don't know if this is something you need to do, but you can check if the Quill Object has already been initialized and skipping a duplication if it has, by doing:
data.filter(function(el, index){ return !quillValueContainer[index]; }).foreach(...
Or
data.forEach(function(el, index) {
if(quillValueContainer[index]) return;
quillValueContainer[index] = new Quill(el['editor']);
quillValueContainer[index].on('text-change', logHtmlContent);
});
I'm trying to create an array in Javascript with a size that is equivalent to the number of times a certain class is found in the DOM, and then iterate through it to grab the text from an input field present in that class. I can easily do this like so:
var count = 0;
$('.className').each(function() {
count++;
});
var classes = new Array(count);
count = 0;
$('.className input[type=text]').each(function() {
classes[count++] = $(this).val();
});
This looks like a lot of code for what seems to be a relatively simple task. Is there a more efficient or less lengthy way of doing this?
Thanks
It looks like you want this :
var classes = $('.className input[type=text]').map(function(){
return this.value
}).get();
But it's a guess : it's not clear why you start by counting all elements of the class and then iterate on the inputs.
You can construct an array of elements directly from your selector via the makeArray function, then transform the result using a map.
var classes = $.makeArray($('.className input[type=text]')).map(function() {
return $(this).val();
});
Use jQuery's map function, then get if you need a pure array:
var values = $('.className input[type=text]').map(function() {
return $(this).val();
}).get();
each passes the index, so you don't need to do it yourself:
var classes = [];
$('.className input[type=text]').each(function(index, value) {
classes[index] = $(this).val();
});
Arrays are dynamic and therefore don't need to be initialized. Create a new array, loop through the inputs and push the values to the new array:
var classes = [];
$('.className input[type=text]').each(function(idx, elem) {
classes.push($(elem).val());
});
I want to return the var "source" value for all the element, now when I put the "source" out of each function, it become undefined.I want to return the whole source array. How to do that? any help would be truly appreciated -
function _getSource(){
var product = fpd.getProduct(true);
$(product[0].elements).each(function(i, elem) {
var source = elem.parameters['source'];
})
return source;
alert (source);
}
Assuming that you're actually after an array containing the source property of each element:
function _getSource(){
var product = fpd.getProduct(true);
return $(product[0].elements).map(function(i, elem) {
return elem.parameters['source'];
}).get(); // .get() turns jQuery collection into an array
}
.map is a very good replacement for a .each / push combo. It comes from functional languages where the "map" function just takes an array, transmutes each elements, and returns a new array of those transmuted results.
The final .get is not strictly necessary if you don't mind getting an array-like result back rather than a proper array.
When you write var source you are declaring a new variable scoped to the function of the each callback. Declare it outside and get rid of the var so you are just assigning instead of redeclaring, and you probably also want to build up an array and not just assign. Something like this:
function _getSource(){
var product = fpd.getProduct(true);
var sources = [];
$(product[0].elements).each(function() {
sources.push(elem.parameters['source']);
})
return sources;
}
source is only defined inside the each function because you var'd it there.
Try this instead:
function _getSource() {
return $(fpd.getProduct(true)[0].elements).map(function() {return this.parameters['source'];});
}
What is the cleanest way to put the source attribute string of all images within a div into an array?
I was hoping this would work -
var imageSourceArray = $("#leDiv img").attr('src');
alert(imageSourceArray[3]); //not alerting the source, boo hoo.
Do I need to loop through $("#leDiv img") and add each src string to an array individually? Or is there a more elegant way to do this?
You can use jQuery's map function which is described as:
Pass each element in the current matched set through a function, producing a new jQuery object containing the return values.
For your example:
var mySources = $('#leDiv img').map(function() {
return $(this).attr('src');
}).get();
Edit: Far more elegant solution, there's obviously still some looping involved internally:
var img_sources = $('#leDiv img').map(function(){ return $(this).attr('src') });
You will in fact need to loop over the collection and add sources individually.
var img_sources = [];
$('#leDiv img').each(function(i,e){
img_sources.push($(e).attr('src'))
})
Some background: jQuery.fn.attr() maps to jQuery.access() internally, the key part of which looks like this:
function( elems, key, value, exec, fn, pass ) {
var length = elems.length;
// setter functions omitted here …
// Getting an attribute
return length ? fn( elems[0], key ) : undefined;
}
Note the elems[0] part – only the first item in the collection is fed to the subsequent callback function (jQuery.attr() in fact) responsible for extracting the information.
var imageSourceArray = [];
$('#leDiv img').each(function(){
var src = $(this).attr("src");
imageSourceArray.push(src);
});
alert(imageSourceArray[3]);
you already have the src in a collection when you fetch the the images. It may be more efficient to not store the src attributes in another array:
$('#leDiv img').each(function(i,e){
var dosomethingwith = $(e).attr('src');
})
or you could do:
var ImageCol = $('#leDiv img');
alert(ImageCol[3].attr('src'));
I'm splitting a string into an array, then I want to remove the white space around each element. I'm using jQuery. I'm able to do this successfully with 2 arrays but I know it's not correct. How do I loop thru an array and trim each element so the elements keep that change. Thanks for any tips. Here is my working code using two array. Please show me the correct way to do this.
var arVeh = vehicleText.split("|");
var cleanArry = new Array();
$.each(arVeh, function (idx, val) {
cleanArry.push($.trim(this));
});
Cheers,
~ck in San Diego
You don't even really need the idx or val parameters. This appears to work on jsFiddle:
var cleanVehicles = [];
$.each(vehicleText.split("|"), function(){
cleanVehicles.push($.trim(this));
});
EDIT: Now that I've seen what you're really after, try using map:
var cleanVehicles = $.map(vehicleText.split("|"), $.trim);
I'm going to suggest not using the overhead of jQuery for a simple for-loop...
var arVeh = vehicleText.split("|");
for (var i = 0, l = arVeh.length; i < l; ++i) {
arVeh[i] = $.trim(arVeh[i]);
});
Alternatively, get rid of the whitespace from the beginning, and avoid the need for another loop at all.
var arVeh = $.trim(vehicleText).split(/\s*\|\s*/);
Without 'creating' an array in the javascript code (an array will nevertheless be created in memory)
vehicles = $.map(vehicleText.split("|"), function(e,i) { return $.trim(e) });
var my_arr = [' cats', 'dogs ', ' what '];
$.each(my_arr, function (id, val) {
my_arr[id] = $.trim(val);
});
console.log(my_arr);
This will trim the value and set it to the indexed item.
You don't have to use JQuery. Here is your vanilla solution:
testArray.map(Function.prototype.call, String.prototype.trim);
Function.prototype.call calls trim() on each of the elements of the testArray. As simple as that!
Could you not just do this?
var arVeh = vehicleText.split("|");
$.each(arVeh, function (idx, val) {
arVeh[idx] = $.trim(this);
});
//a simple function
function trimArray(dirtyArray){
$.map(dirtyArray.split("|"), function(idx, val){
return $.trim(this);
});
}
trimArray(vehicleArray);
should do the trick
Or you could use some of the awesome power of javascript and use array.prototype. I'm still a little new at using the .prototype of any object... so this isnt guaranteed to work (but it certainly can be done).
Array.prototype.trim = function (){
$.map(dirtyArray.split("|"), function(idx, val){
return $.trim(this);
});
}
someArray.trim()
You need these two jQuery functions:
1.) iterate through array element with ability to edit items:
http://api.jquery.com/jquery.map/
2.) remove blank spaces from beginning and end of a string:
http://api.jquery.com/jQuery.trim/
Use them this way:
array = $.map(array, function(value) { return value.trim();});
Check this JSFiddle:
https://jsfiddle.net/L00eyL4x/49/