0👍
✅
Solution
You need a function that determines the position of a specific child element within a certain parent element in an array. If you’re interested in the parent’s position, then the child element index should be -1 (so that in the code, we know this is not a real child, and when we increment it by +1, it remains at 0, thus not affecting the result).
const getNo = (array, parentIndex, childIndex = -1) => {
// Start 0
let number = 0;
// Adding child counts of previous elements
for (let i = 0; i < parentIndex; i++) {
const parent = array[i];
if (!parent) break;
number += parent.childs.length;
}
// Adding parentIndex
number += parentIndex + 1;
// Adding childIndex (if -1 then 0 = skip)
number += childIndex + 1;
return number;
}
Or, if you prefer shorter solutions, you can also use Array.propery.reduce()
.
const getNo = (array, parentIndex, childIndex = -1) => array.reduce((total, parent, index) => index < parentIndex && parent ? total + parent.childs.length : total, 0) + parentIndex + 1 + childIndex + 1;
- What does the Array method
reduce
do? – StackOverflow answers
Example
// CDN Vue Import
const { createApp, ref } = Vue
const app = createApp({
setup() {
const data = [{
id: 1,
name: "parent 1",
childs: [{
id: 2,
name: "child 1-1"
}, {
id: 10,
name: "child 1-2"
}]
}, {
id: 4,
name: "parent 2",
childs: [{
id: 6,
name: "child 2-1"
}, {
id: 7,
name: "child 2-2"
}, {
id: 8,
name: "child 2-3"
}]
}, {
id: 31,
name: "parent 3",
childs: [{
id: 32,
name: "child 3-1"
}, {
id: 310,
name: "child 3-2"
}]
}]
const getNo = (array, parentIndex, childIndex = -1) => {
// Start 0
let number = 0
// Adding child counts of previous elements
for (let i = 0; i < parentIndex; i++) {
const parent = array[i]
if (!parent) break
number += parent.childs.length
}
// Adding parentIndex
number += parentIndex + 1
// Adding childIndex (if -1 then 0 = skip)
number += childIndex + 1
return number
}
return { data, getNo }
},
}).mount('#app')
<script src="https://unpkg.com/vue@3.3.4/dist/vue.global.prod.js"></script>
<div id="app">
<table>
<thead>
<tr>
<th>No.</th>
<th>Parent</th>
<th>Child</th>
</tr>
</thead>
<tbody>
<template v-for="(parent, parentIndex) in data" :key="parent.id">
<tr>
<td>{{ getNo(data, parentIndex) }}</td>
<td>{{ parent.name }}</td>
<td></td>
</tr>
<template v-for="(child, childIndex) in parent.childs" :key="child.id">
<tr>
<td>{{ getNo(data, parentIndex, childIndex) }}</td>
<td></td>
<td>{{ child.name }}</td>
</tr>
</template>
</template>
</tbody>
</table>
</div>
Source:stackexchange.com