0

How can I read and store each span id inside of div class v-h-box into a separate list and further sort each list.

I want output as [[2,3,4,5],[1,6,7,8]]

let x = document.querySelectorAll(".v-h-box");
let y = Array.from(x);
console.log(y);

let answerArray = [];
y.forEach((item, index) => {
    if(item.children.length >= 1){
        answerArray.push(item.children[0].id)
    }
})
<div class="v-h-box">
  <span class="v-h-multiple">
    <span id="4" draggable="true"> Tokoyo </span>
    <span id="2" draggable="true"> UK </span>
    <span id="5" draggable="true"> USA </span>
    <span id="3" draggable="true"> New York </span>
  </span>
</div>
<div class="v-h-box">
  <span class="v-h-multiple">
    <span id="8" draggable="true"> Paris </span>
    <span id="6" draggable="true"> Mumbai </span>
    <span id="7" draggable="true"> India </span>
    <span id="1" draggable="true"> France </span>
  </span>
</div>
0stone0
  • 34,288
  • 4
  • 39
  • 64
Test
  • 25
  • 3

3 Answers3

1

You can use querySelectorAll to find all div and using Array.from and array#map you can get all id attribute of span.

const divs = document.querySelectorAll('.v-h-box');
const result = Array
  .from(divs)
  .map(div => {
    const spans = div.querySelectorAll('.v-h-multiple span');
    return Array
      .from(spans)
      .map(span => Number(span.getAttribute('id')))
      .sort((a,b) => a - b);
  });
console.log(result);
<div class="v-h-box">
  <span class="v-h-multiple">
    <span id="4" draggable="true"> Tokoyo </span>
    <span id="2" draggable="true"> UK </span>
    <span id="5" draggable="true"> USA </span>
    <span id="3" draggable="true"> New York </span>
  </span>
</div>
<div class="v-h-box">
  <span class="v-h-multiple">
    <span id="8" draggable="true"> Paris </span>
    <span id="6" draggable="true"> Mumbai </span>
    <span id="7" draggable="true"> India </span>
    <span id="1" draggable="true"> France </span>
  </span>
</div>
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51
0

Since the <spans> that you're trying to find are childs of the v-h-multiple div, you'll need to go a children deeper

I've used this ([...]) technique to create an array of the children so we can use map() to return only the ids.

Then using sort() to sort them.

I've also added parseInt in the map to convert the ID's to integers.

let x = document.querySelectorAll(".v-h-box");
let y = Array.from(x);

let answerArray = [];
y.forEach((item, index) => {
    if (item.children.length >= 1) {
        let childIds = [...item.children[0].children].map((c) => parseInt(c.id));
        answerArray.push(childIds.sort((a, b) => a - b))
    }
})

console.log(answerArray);
<div class="v-h-box">
  <span class="v-h-multiple">
    <span id="4" draggable="true"> Tokoyo </span>
    <span id="2" draggable="true"> UK </span>
    <span id="5" draggable="true"> USA </span>
    <span id="3" draggable="true"> New York </span>
  </span>
</div>
<div class="v-h-box">
  <span class="v-h-multiple">
    <span id="8" draggable="true"> Paris </span>
    <span id="6" draggable="true"> Mumbai </span>
    <span id="7" draggable="true"> India </span>
    <span id="1" draggable="true"> France </span>
  </span>
</div>
[
  [
    2,
    3,
    4,
    5
  ],
  [
    1,
    6,
    7,
    8
  ]
]
0stone0
  • 34,288
  • 4
  • 39
  • 64
  • Using `.sort()` without a comparator is not enough, because it will perform a natural sort instead of a numeric sort. – Terry Jun 21 '21 at 11:39
0

Generally you just need a nested loop, instead of that single [0]:

let x = document.querySelectorAll(".v-h-box");
let y = Array.from(x);

let answerArray = [];
y.forEach((item, index) => {
  if (item.children.length >= 1) {
    let xx = item.children[0].children;
    let yy = Array.from(xx);

    let subArray = [];
    yy.forEach(span => subArray.push(parseInt(span.id)));
    answerArray.push(subArray.sort((a, b) => a - b));
  }
})
console.log(JSON.stringify(answerArray));
<div class="v-h-box">
  <span class="v-h-multiple">
  <span id="4" draggable="true"> Tokoyo </span>
  <span id="2" draggable="true"> UK </span>
  <span id="5" draggable="true"> USA </span>
  <span id="3" draggable="true"> New York </span>
  </span>
</div>
<div class="v-h-box">
  <span class="v-h-multiple">
  <span id="8" draggable="true"> Paris </span>
  <span id="6" draggable="true"> Mumbai </span>
  <span id="7" draggable="true"> India </span>
  <span id="1" draggable="true"> France </span>
  </span>
</div>

However, if you are allowed to use Array.from(), a relatively new construct in JS, you can presumably also use for...of, and a much shorter code:

let answerArray = [];
for (let item of document.querySelectorAll(".v-h-box"))
  if (item.children.length >= 1) {
    let subArray = [];
    for (let span of item.children[0].children)
      subArray.push(parseInt(span.id));
      answerArray.push(subArray.sort((a,b)=>a-b));
  }
console.log(JSON.stringify(answerArray));
<div class="v-h-box">
  <span class="v-h-multiple">
  <span id="4" draggable="true"> Tokoyo </span>
  <span id="2" draggable="true"> UK </span>
  <span id="5" draggable="true"> USA </span>
  <span id="3" draggable="true"> New York </span>
  </span>
</div>
<div class="v-h-box">
  <span class="v-h-multiple">
  <span id="8" draggable="true"> Paris </span>
  <span id="6" draggable="true"> Mumbai </span>
  <span id="7" draggable="true"> India </span>
  <span id="1" draggable="true"> France </span>
  </span>
</div>

And then you can go with map/reduce magics sparing a line here and there (like for creating the arrays):

let answerArray = Array.from(document.querySelectorAll(".v-h-box"))
  .reduce((result, item) => {
    if (item.children.length >= 1)
      result.push(Array.from(item.children[0].children)
        .map(span => parseInt(span.id)).sort((a, b) => a - b));
    return result;
  }, []);
console.log(JSON.stringify(answerArray));
<div class="v-h-box">
  <span class="v-h-multiple">
  <span id="4" draggable="true"> Tokoyo </span>
  <span id="2" draggable="true"> UK </span>
  <span id="5" draggable="true"> USA </span>
  <span id="3" draggable="true"> New York </span>
  </span>
</div>
<div class="v-h-box">
  <span class="v-h-multiple">
  <span id="8" draggable="true"> Paris </span>
  <span id="6" draggable="true"> Mumbai </span>
  <span id="7" draggable="true"> India </span>
  <span id="1" draggable="true"> France </span>
  </span>
</div>

Which is shorter, but not necessarily more readable than the previous one.

tevemadar
  • 12,389
  • 3
  • 21
  • 49