You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Lodash高效合并相同subsets的JavaScript数组对象

Efficiently Merge Font Objects by Shared Subsets (No Lodash Needed)

Let's cut to the chase—your current Lodash-based approach works, but it's not the most efficient when dealing with large datasets. The core issue is that uniqueBy plus subsequent grouping adds extra overhead. Instead, we can use a plain JavaScript lookup object to do this in a single pass, which is way faster (O(n) time complexity vs. the O(n log n) or worse of your original method).

First, let's recap what we're working with:

Input

const originalFonts = [
  {
    subsets: [
      { start: '0020', end: '007F' },
      { start: '0020', end: '007G' },
      { start: '0020', end: '007G' }
    ],
    fontFormat: 'woff2',
    src: 'estPath1/'
  },
  {
    subsets: [
      { start: '0020', end: '007F' },
      { start: '0020', end: '007G' },
      { start: '0020', end: '007G' }
    ],
    fontFormat: 'woff',
    src: 'estPath2/'
  }
];

Desired Output

[
  {
    subset: [
      { start: '0020', end: '007F' },
      { start: '0020', end: '007G' },
      { start: '0020', end: '007G' }
    ],
    webFontList: [
      { fontFormat: 'woff2', src: 'estPath1/' },
      { fontFormat: 'woff', src: 'estPath2/' }
    ]
  }
]

The Efficient One-Pass Solution

Here's how to do it with vanilla JS, no external libraries:

function mergeFontsBySubset(fonts) {
  const subsetMap = {};
  const result = [];

  for (const font of fonts) {
    // Create a unique key for the subsets array
    // JSON.stringify works here because the subset objects have consistent order/structure
    const subsetKey = JSON.stringify(font.subsets);

    if (subsetMap[subsetKey]) {
      // We've seen this subset before—add the font to the webFontList
      subsetMap[subsetKey].webFontList.push({
        fontFormat: font.fontFormat,
        src: font.src
      });
    } else {
      // New subset—create a new entry and add it to our map and result array
      const newEntry = {
        subset: [...font.subsets], // Optional: deep clone if you want to avoid reference issues
        webFontList: [{
          fontFormat: font.fontFormat,
          src: font.src
        }]
      };
      subsetMap[subsetKey] = newEntry;
      result.push(newEntry);
    }
  }

  return result;
}

// Usage
const mergedFonts = mergeFontsBySubset(originalFonts);
console.log(mergedFonts);

Why This Is Better

  • Single pass: We only iterate over the original array once, instead of first deduplicating then grouping.
  • O(1) lookups: The object-based map lets us check if a subset exists instantly, no looping through a deduplicated list every time.
  • No external dependencies: You don't need Lodash anymore, which reduces bundle size if that's a concern.

Edge Case Note

If your subsets arrays might have the same objects but in a different order, JSON.stringify will treat them as different keys. To fix that, you can sort the subsets first (or sort the keys within each subset object) before stringifying. For example:

// Helper to create a consistent key even if subset order varies
function getSubsetKey(subsets) {
  // First sort the subsets by start/end, then stringify
  const sortedSubsets = [...subsets].sort((a, b) => {
    if (a.start !== b.start) return a.start.localeCompare(b.start);
    return a.end.localeCompare(b.end);
  });
  // Also ensure object keys are ordered (not necessary in modern JS, but safe)
  return JSON.stringify(sortedSubsets.map(subset => ({start: subset.start, end: subset.end})));
}

Then replace JSON.stringify(font.subsets) with getSubsetKey(font.subsets) in the function.

内容的提问来源于stack exchange,提问作者iAviator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:02:52