getattribute from each element in array

64 Views Asked by At

i have this code and i want to get a new array with the href attribute of each element in the array; maybe there is a different way to do it

let countries = document.querySelectorAll('.el');
let countriesList = Array.prototype.slice.call(countries);
let arra = countriesList.map(link);
function link() {
   for(let i = 0; i < countriesList.length; i++) {
      countriesList[i].getAttribute('href');
   }  
}
console.log(arra)
<div>
  <a class='el' href='italy.php'>Italy</a>
  <a class='el' href='france.php'>France</a>
  <a class='el' href='japan.php'>Japan</a>
  <a class='el' href='china.php'>China</a>
</div>

4

There are 4 best solutions below

0
jsejcksn On BEST ANSWER

You can avoid iterating the collection more than once by instantiating an empty array, then pushing each value into it in a for...of loop:

const hrefs = [];

for (const anchor of document.querySelectorAll(".el")) {
  hrefs.push(anchor.getAttribute("href"));
}

console.log(hrefs); // ["italy.php", "france.php", "japan.php", "china.php"]
<div>
  <a class="el" href="italy.php">Italy</a>
  <a class="el" href="france.php">France</a>
  <a class="el" href="japan.php">Japan</a>
  <a class="el" href="china.php">China</a>
</div>

0
brk On

You can convert the nodelist to an array and use map to get array of href

let arra = [...document.querySelectorAll('.el')].map(item => item.getAttribute('href'))
console.log(arra)
<div>
  <a class='el' href='italy.php'>Italy</a>
  <a class='el' href='france.php'>France</a>
  <a class='el' href='japan.php'>Japan</a>
  <a class='el' href='china.php'>China</a>
</div>

1
Konrad On

A function passed to map is called once per element and must return a value

let countries = document.querySelectorAll('.el');
let countriesList = Array.prototype.slice.call(countries);
let arra = countriesList.map(link);
function link(country) {
  return country.getAttribute('href');
}
console.log(arra)
<div>
  <a class='el' href='italy.php'>Italy</a>
  <a class='el' href='france.php'>France</a>
  <a class='el' href='japan.php'>Japan</a>
  <a class='el' href='china.php'>China</a>
</div>

You could also skip map

let countries = document.querySelectorAll('.el');
let countriesList = Array.prototype.slice.call(countries);
let arra = link();
function link() {
   const array = []
   for(let i = 0; i < countriesList.length; i++) {
      array.push(countriesList[i].getAttribute('href'));
   }
   return array
}
console.log(arra)
<div>
  <a class='el' href='italy.php'>Italy</a>
  <a class='el' href='france.php'>France</a>
  <a class='el' href='japan.php'>Japan</a>
  <a class='el' href='china.php'>China</a>
</div>

2
mplungjan On

Your function link() does not return anything and has an unnecessary loop.

Also Array.prototype.slice.call(countries); is no longer an elegant way to get an array from a collection. Array.from is by far the most elegant and descriptive way. AND it takes a function to run while mapping! (Thanks Nick)

Here is your fixed code still using a separate function to pass to the map-function of Array.from

const countryLinks = document.querySelectorAll('.el');

// const getCountry= el => el.getAttribute('href').split('.')[0]; // callback
const getCountry = el => el.textContent; // alternative callback
// Array.from is more descriptive than spread, and we can add the callback
const countryArray = Array.from(countryLinks, getCountry);
console.log(countryArray);
<div>
  <a class='el' href='italy.php'>Italy</a>
  <a class='el' href='france.php'>France</a>
  <a class='el' href='japan.php'>Japan</a>
  <a class='el' href='china.php'>China</a>
</div>