如何对数组中连续同值对象分组并实现下拉展开功能?
Alright, let's solve this problem step by step. First, we need to group only consecutive objects that share the same color value (non-consecutive matches stay separate), then turn those groups into a collapsible dropdown list as you described.
Step 1: Group Consecutive Items
First, let's write a helper function to process the original data array and group consecutive matches. This function will iterate through the array, building groups as it goes—only adding an item to the current group if it has the same color as the last item in the group.
const data = [ {color: "green", number: 23}, {color: "red", number: 25}, {color: "green", number: 27}, {color: "green", number: 26}, {color: "orange", number: 30} ]; function groupConsecutiveSameColor(arr) { if (!arr.length) return []; const groups = []; let currentGroup = [arr[0]]; for (let i = 1; i < arr.length; i++) { const currentItem = arr[i]; const lastGroupItem = currentGroup[currentGroup.length - 1]; // If current item matches the group's color, add it to the group if (currentItem.color === lastGroupItem.color) { currentGroup.push(currentItem); } else { // Otherwise, save the current group and start a new one groups.push(currentGroup); currentGroup = [currentItem]; } } // Don't forget to add the final group to the array groups.push(currentGroup); return groups; } // Generate our grouped data const groupedData = groupConsecutiveSameColor(data);
Running this will give us groups like:
[ [{color: "green", number:23}], [{color: "red", number:25}], [{color: "green", number:27}, {color: "green", number:26}], [{color: "orange", number:30}] ]
Step 2: Build the Collapsible Dropdown
Next, we'll take these groups and render a dropdown where single-item groups show just the color, and multi-item groups show the color plus a count (like green(2)). Clicking the count-labeled items will expand to show all objects in the group.
We'll use plain HTML and JavaScript for this example (works in any browser without frameworks):
<!-- Container to hold our dropdown --> <div id="colorDropdown" style="padding: 10px; font-family: Arial, sans-serif;"></div> <script> // Include the groupConsecutiveSameColor function and data here const dropdownContainer = document.getElementById('colorDropdown'); function buildCollapsibleDropdown(groups) { groups.forEach(group => { // Create a container for each group const groupWrapper = document.createElement('div'); groupWrapper.style.margin = '8px 0'; // Create the clickable header for the group const groupHeader = document.createElement('button'); groupHeader.style.padding = '8px 16px'; groupHeader.style.border = 'none'; groupHeader.style.borderRadius = '4px'; groupHeader.style.backgroundColor = '#f0f0f0'; groupHeader.style.cursor = 'pointer'; groupHeader.style.fontSize = '14px'; // Set the header text: show count only if group has multiple items const headerText = group.length === 1 ? group[0].color : `${group[0].color}(${group.length})`; groupHeader.textContent = headerText; // Create the collapsible content area const groupContent = document.createElement('div'); groupContent.style.display = 'none'; // Hidden by default groupContent.style.marginLeft = '24px'; groupContent.style.marginTop = '6px'; groupContent.style.fontSize = '14px'; // Add each item in the group to the content area group.forEach(item => { const itemElement = document.createElement('div'); itemElement.textContent = `${item.color} - Number: ${item.number}`; itemElement.style.padding = '4px 0'; groupContent.appendChild(itemElement); }); // Add click handler to toggle content visibility groupHeader.addEventListener('click', () => { groupContent.style.display = groupContent.style.display === 'none' ? 'block' : 'none'; }); // Add header and content to the group wrapper groupWrapper.appendChild(groupHeader); groupWrapper.appendChild(groupContent); dropdownContainer.appendChild(groupWrapper); }); } // Render the dropdown buildCollapsibleDropdown(groupedData); </script>
How It Works
- Single-item groups (like the first
greenorred) show just the color text and don't expand (though you could add expansion if needed). - Multi-item groups (like the two consecutive
greens) showgreen(2)—clicking this button will toggle the visibility of the two underlying objects. - The styling is minimal but easy to customize to match your app's design.
内容的提问来源于stack exchange,提问作者Igor-Vuk

