Reputation: 54
I am wanting to merge 2 lists together with jQuery but I am not even sure where to start. Instead of prepending or appeding the list I need to place each item between the other list. Not quite sure the best way to word this but basically I have the following HTML
<ul>
<li>A<li>
<li>B<li>
<li>C<li>
<li>D<li>
<li>E<li>
</ul>
<ul>
<li>1<li>
<li>2<li>
<li>3<li>
<li>4<li>
<li>5<li>
</ul>
And I am wanting a way to get the following:
<ul>
<li>A<li>
<li>1<li>
<li>B<li>
<li>2<li>
<li>C<li>
<li>3<li>
<li>D<li>
<li>4<li>
<li>E<li>
<li>5<li>
</ul>
Upvotes: 1
Views: 59
Reputation: 11116
This is a concept called array stitching, and can be accomplished with the following code:
Note - This approach works even if your two arrays are of unequal lengths!
$(function () {
var lists = $("ul");
// create real arrays from jQuery collections
var list1 = Array.apply(null, lists.eq(0).find("li"));
var list2 = Array.apply(null, lists.eq(1).find("li"));
function stitch(arr1, arr2) {
var newArr = [];
while (arr1.length && arr2.length) {
newArr.push(arr1.shift());
newArr.push(arr2.shift());
}
return newArr.concat(arr1, arr2);
}
var newList = stitch(list1, list2);
$("#results").html(newList);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<ul id="results">
</ul>
What is really cool is the ability to use ES6 gather/spread syntax to easily create a generic function that can stitch together n number of arrays. Here's how that can be done:
$(function () {
var lists = $("ul");
// create real arrays from jQuery collections
var list1 = Array.apply(null, lists.eq(0).find("li"));
var list2 = Array.apply(null, lists.eq(1).find("li"));
var list3 = Array.apply(null, lists.eq(2).find("li"));
function stitch(...arrs) {
var newArr = [];
while (arrs.some(arr=>arr.length)) {
arrs.forEach(arr=>{
if (arr.length) {
newArr.push(arr.shift());
}
});
}
return newArr;
}
var newList = stitch(list1, list2, list3);
$("#results").html(newList);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>4</li>
<li>5</li>
</ul>
<ul>
<li>Do</li>
<li>Re</li>
<li>Me</li>
<li>Fa</li>
<li>So</li>
<li>Fa</li>
<li>So</li>
</ul>
<ul id="results">
</ul>
Upvotes: 1
Reputation: 21102
You can treat a selector from jQuery as any other array, so you can map the two selections into a new array containing the intertwined result (a1b2c3..) and move the elements into a new parent. Sometimes the hardest part of finding an answer is knowing how to word the problem.
Keep in mind you'll need to do some adjustments if your lists are not of the same length.
//Intertwine them
var intertwined = $.map($("#first li"), function(v, i) {
return [v, $("#second li")[i]];
});
//Remove them
$(intertwined).remove();
//Add them to a new parent
$.each(intertwined, function(i, e) {
$("#intertwined").append($(e))
});
//Clean old parents
$("#first, #second").remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="first">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<ul id="second">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
</ul>
<ul id="intertwined">
</ul>
Upvotes: 3
Reputation: 6467
Considering that:
Following code should work (see inline comments):
// Getting all li items from each list
var firstLIs = $('ul#first li');
var secondLIs = $('ul#second li');
// Getting the length of the list
var total = firstLIs.length;
// Var that will store the result (merged LIs)
var content = [];
for (var i = 0; i < total; i++) {
// Feeding our content array with LI items from both list
content.push(firstLIs[i], secondLIs[i]);
}
// Overriding content from second list with the newly merged LIs
$('ul#second').html(content);
Upvotes: 0