Javascript/jquery create array from elements with same rel? - javascript

How can you create an array with from a set of elements with same rel?
Eg:
<a rel='array' id='2' url='aa'></a>
<a rel='array' id='5' url='bb'></a>
<a rel='array' id='8' url='cc'></a>
Array:
[2] > aa
[5] > bb
[8] > cc
I put each URL as value just to use something. But having the IDs ordered should be enough.
How can this be done?

const anchors = document.getElementsByTagName('a'), arr = [];
for (let i = 0; i < anchors.length; i++){
let current = anchors[i];
if(current.getAttribute('rel') == 'array') {
// arr.push(current.getAttribute('url'));
arr.push({ 'id' : current.id, 'url' : current.getAttribute('url') });
}
}
http://jsfiddle.net/8ScSH/
Or, more succinctly:
const anchors = [...document.getElementsByTagName('a')];
const arrs = anchors.filter(x => x.getAttribute('rel') === 'array')
.map(x => { return { 'id': x.id, 'url': x.getAttribute('url') } });

Not enough jquery!
var arr = [];
$('a[rel="array"]').each(function(){
arr.push($(this).attr('url'));
});

Very easy if you're using jquery:
var arr = [];
$('a[rel="array"]').each(function() {
arr.push($(this).attr('url'));
});
​
Fiddle

var itemArray = [];
$("a[rel='array']").each(function() { itemArray.push($(this).attr("url") });

Try
var a = {};
$('#wrap a').each(function() {
if($(this).attr('rel') === "array") {
a[$(this).attr('id')] = $(this).attr('url');
}
});​​
An array won't cut it, you need an object. Here live: http://jsfiddle.net/martincanaval/rAPkL/

var elements = [];
$('a[rel="array"]').each(function() {
elements[this.id] = $(this).attr('url');
});
Note that this creates a sparse array with only the index values specified by the element ids, which doesn't make much sense to me, but that's what you asked for. It really doesn't make sense if any of the ids can be non-numeric - if so you should use an object rather than an array, i.e.:
var elements = {};
"I put each URL as value just to use something. But having the IDs ordered should be enough."
If your intention is to get an array of the ids then you can do this:
var elementIds = [];
$('a[rel="array"]').each(function() {
elementIds.push(this.id);
});
That would create the array ['2', '5', '8'] where the ids will be in the order that they appear within your source html.
However, just saying $('a[rel="array"]') gives you a jQuery object that is an array-like structure holding all the matching elements - that's why we can iterate over each of the elements using the .each() method. So it's possible that whatever you're really trying to do can be done directly with jQuery rather than setting up your own array.

Related

How to store values in an array Jquery?

I have a function:
chatManager.connect()
.then(currentUser => {
var final = currentUser.users;
var name = [];
var arr = [];
$.each(final,function(index,val){
if(val.name != '{{Auth::user()->name}}')
{
console.log(val.id); //Harry, Ron (each in different line)
arr = name.push(val.id)
console.log(arr); //1,2 (each in different line)
var presence = val.presenceStore.store.{{Auth::user()->name}}{{Auth::user()->id}}
}
});
I want the arr to be an array like [Harry,Ron]. Why is it not working? I am new to Jquery. Please help.
arr = name.push(val.id) is your problem. push returns the array's new length, not an array. Simply replace the line with
arr.push(val.id);

Return Object in Array if Property Match

Here is the scenario:
There is a parameter titledlistOfSelectedProductIdsthat contains
all of the selected ids.
There is another list titled listOfAllPossibleProducts, which
contains a list of objects. That object contains a ProductId,
ProductName, and ProductCode. It looks something like this:
The task at hand:
I need to loop through my listOfSelectedProductIds. If the ProductId matches a ProductId from listOfAllPossibleProducts, then I need to return that object.
Here is what I am doing:
function SelectedProducts(listOfSelectedProductIds){
for (var index = 0; index < listOfSelectedProductIds.length; index++) {
var currentItem = listOfSelectedProductIds[index];
var desiredProduct = _.contains(listOfAllPossibleProducts, currentItem);
if (desiredProduct === true) {
return listOfAllPossibleProducts[index];
}
}
}
What's currently happening:
My loop is getting the selected id as expected i.e. currentItem, but _.contains(...)
always returns false.
Question:
What is the best way to find the objects in
listOfAllPossibleProducts that have ProductIds that match my
ProductIds in the listOfSelectedProductIds
How about using _.filter:
var result = _.filter(listOfAllPossibleProducts, function (el) {
return _.contains(listOfSelectedProductIds, el.id);
});
Or the non-underscore method:
var result = listOfAllPossibleProducts.filter(function (el) {
return listOfSelectedProductIds.indexOf(el.id) > -1;
});
DEMO
create another structure productsByProductId once!
var productsByProductId = {};
listOfAllPossibleProducts.forEach(p => {
productsByProductId[p.ProductId()] = p
});
and maybe a helper function
function getProductById(id){
return productsByProductId[id];
}
and use this to map the ids to the nodes
var selectedProducts = listOfSelectedProductIds.map(getProductById)

Create an array or object of elements with the same dynamic class

I currently the following jQuery collection / object:
[li.row-0, li.row-1, li.row-2, li-row-2, li.row-2, li.row-3]
Each class name is dynamically added to each element by a previous method. The only consistent part of the class name is row-. The number can be anywhere from 0 - ∞.
I want to create a new array or object of elements that are grouped by same dynamic class name:
[li.row-0]
[li.row-1]
[li.row-2, li.row-2, li.row-2, li.row-2]
[li.row-3]
The above is just a guess of the outcome, as I am not 100% sure how best to achieve this.
The aim is to be able to loop through .row-0, .row-1, .row-2, .row-3 and do something with the elements in each individual row.
I would do this :
var map = [].reduce.call(arr, function(map, v){
(map[v.className]||(map[v.className]=[])).push(v);
return map;
}, {});
var arr2 = [];
for (var className in map) arr2.push(map[className]);
The reduce builds a map having as keys the class names and with values the arrays of the elements having that class name.
I use [].reduce.call(arr, instead of arr.reduce( so that it works for standard arrays, jQuery collections, nodelists, etc.
Then the loop builds an array from that map. You might find the map more useful than the final array.
This shows you a general way of achieving this, though you're probably using elements rather than strings, but hopefully this will help
var tst = ['li.row-0','li.row-1','li.row-2','li.row-2','li.row-2','li.row-3'];
var grouped = [];
for(var i in tst)
{
var text = tst[i];
var num = text.replace('li.row-','');
if(!grouped[num]) grouped[num] = [];
grouped[num].push(text);
}
console.log(grouped);//[["li.row-0"], ["li.row-1"], ["li.row-2", "li.row-2", "li.row-2"], ["li.row-3"]]
Using elements:
var tst = [li.row-0,li.row-1,li.row-2,li.row-2,li.row-2,li.row-3];
var grouped = [];
for(var i in tst)
{
var text = tst[i].className;
var num = text.replace('row-','');
if(!grouped[num]) grouped[num] = [];
grouped[num].push(text);
}
console.log(grouped);//[["li.row-0"], ["li.row-1"], ["li.row-2", "li.row-2", "li.row-2"], ["li.row-3"]]
This method is more verbose and allows more complex grouping if need be (if other attributes come into play)
I would do something like the following:
var arr = ['li.row-0', 'li.row-1', 'li.row-2', 'li.row-2', 'li.row-2', 'li.row-3'];
var result = {};
$.each(arr, function (index, item) {
var ind = item.toString().split('row-')[1];
(result[ind] || (result[ind] = [])).push(item);
});
console.log(result);

How to push onto a multidimensional associative array

I'm looping through some HTML form elements on a page like so.
var itemsArray = new Array();
$('input[type="text"].qty').each(function(index) {
if($(this).val()) {
itemsArray[index]['qty'] = $(this).val();
itemsArray[index]['itemPrice'] = $(this).parents('.control-group').find('.itemPrice').val();
itemsArray[index]['itemID'] = $(this).parents('.control-group').find('.itemID').val();
}
});
The index i'm hoping to be 0,1,2,3 etc.. like a regular array. With the sub elements being associative and assigned to various values.
I'm getting this error in the console.
TypeError: itemsArray[index] is undefined
You need to make sure each item in the outer array is initialized before you start using it. Note, I changed to object notation below just for clarity.
$('input[type="text"].qty').each(function(index) {
if($(this).val()) {
itemsArray[index] = {};
itemsArray[index].qty = $(this).val();
itemsArray[index].itemPrice = $(this).parents('.control-group').find('.itemPrice').val();
itemsArray[index].itemID = $(this).parents('.control-group').find('.itemID').val();
}
});
Consider using an array of objects. Arrays in Javascript are not really intended to be used in the way you are (the multidimensional part). Also itemsArray = [] is preferred over new Array().
var itemsArray = [];
$('input[type="text"].qty').each(function(index) {
if($(this).val()) {
itemsArray.push({
qty : $(this).val(),
itemPrice : $(this).parents('.control-group').find('.itemPrice').val(),
itemID : $(this).parents('.control-group').find('.itemID').val()
});
}
});
It means what it says. itemsArray[index] is undefined, and you cannot assign properties on this. Notice that you don't have a "multidimensional array", but just an array of objects. For each new index, you will need to create a new object.
var $this = $(this);
if ($this.val()) {
var $parent = $(this).parents('.control-group'); // .closest() should suffice
itemsArray[index] = {
qty: $this.val(),
itemPrice: $parent.find('.itemPrice').val(),
itemID: $parent.find('.itemID').val()
};
}

Remove element from list - JQuery/JavaScript

I have a list like this in a div:
<div id="x">5,2,3,1,4,9,8</div>
How do I simply remove a given element from this list?
JQuery or JavaScript may be used.
Please note that the numbers in the list are unique and they are coming in from a database of type int(11), they are not in any sort of order.
Any help appreciated guys...
First, get the text:
var text=$("#x").text();
Then split it:
var items=text.split(',');
If there's no items, you'll have an empty string as the only element of the array. If so, empty the array:
if(items.length==1&&items[0]=="") {
items=[];
}
Now convert everything to an integer: (note that this step isn't actually required, but if you're doing anything else with items, it's nice to have)
items=items.map(function(str) { return parseInt(str, 10); });
Put the item you want to remove in a variable:
var itemToRemove=3;
Find that in the array:
var index=items.indexOf(itemToRemove);
If it was found, splice it out of the array:
if(index!==-1) {
items.splice(index, 1);
}
Join the items back together:
text=items.join(',');
Put it back in the element:
$("#x").text(text);
Try this with toRemove equal to 5, 3, or 8 to see that it works for all cases:
var toRemove = 3; // the number you want to remove
$('#x').text($('#x').text().replace(new RegExp(toRemove + ',?'
+ '|,?' + toRemove + '$'), ''));
See example →
Using jQuery's grep-method may be an option too:
var toRemove=1;
$('#x').text( $.grep($('#x').text().split(','),
function (a) { return a != toRemove; }).join(','));
To remove multiple items:
var toRemove=[1,8,3];
$('#x').text( $.grep($('#x').text().split(','),
function (a) { return $.inArray(Number(a),toRemove)<0; })
.join(','));
(But I would prefer a RegExp-solution, it should be much faster)
This is a simple solution that just requires jquery.
function removeFromDiv(which)
{
var data = $("#x").html();
data_arr = data.split(",");
for (var i = 0; i < data_arr.length; i++)
{
if (data_arr[i] == which)
{
data_arr.splice(i, 1);
data = data_arr.join(",");
}
}
$("#x").html(data);
}
then simply run:
removeFromDiv("4");
Doesn't really need to be much harder than this:
function removeIndexFromX(index) {
// Build array from comma-delimited content
var arr = $("#x").text().split(',');
// Remove index (zero-based)
arr.splice(index, 1);
// Replace
$("#x").text(arr.join(','));
}
function removeNumberFromX(num) {
var arr = $("#x").text().split(',');
for (var i = 0; i < arr.length; i++) {
if (arr[i] === num) {
arr.splice(i, 1);
}
}
$("#x").text(arr.join(','));
}
The benefit of split and join is that you can use those to manage delimiters (e.g. commas) for you.

Categories