skip to Main Content

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

Answers


  1. 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>
    Login or Signup to reply.
  2. 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>
    Login or Signup to reply.
  3. 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>
    Login or Signup to reply.
  4. 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search