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

JavaScript:如何基于坐标的相似值对数据进行分组

Hey there! Let's work through this grouping problem you've got—since you mentioned wanting to use reduce, that's exactly the right tool for the job. Let's break down the logic step by step, then jump into code tailored to your scatter plot use case.

Step 1: Define the Similarity Check

First, we need a helper function to judge if two points qualify as "similar" based on your rules:

  • X values differ by 1 year or less
  • Y values differ by 10,000 or less
const isSimilar = (pointA, pointB) => {
  const xDifference = Math.abs(pointA.coordinates.x - pointB.coordinates.x);
  const yDifference = Math.abs(pointA.coordinates.y - pointB.coordinates.y);
  return xDifference <= 1 && yDifference <= 10000;
};
Step 2: Group Points with reduce

We'll use reduce to build our groups incrementally. For each point, we check if it can join any existing group (by verifying it's similar to at least one point in the group). If a match is found, we add it to that group; if not, we create a new group for it.

const groupSimilarPoints = (data) => {
  return data.reduce((groups, currentPoint) => {
    // Find an existing group where the current point matches at least one member
    const matchingGroup = groups.find(group => 
      group.some(point => isSimilar(point, currentPoint))
    );

    if (matchingGroup) {
      matchingGroup.push(currentPoint);
    } else {
      groups.push([currentPoint]);
    }

    return groups;
  }, []);
};
Step 3: Split into Valid Groups & Ungrouped Data

Next, we separate the results into meaningful groups (with 2+ points) and ungrouped data (points that have no similar matches):

const processDataForPlot = (rawData) => {
  const allGroups = groupSimilarPoints(rawData);
  
  const validGroups = [];
  const ungroupedPoints = [];

  allGroups.forEach(group => {
    if (group.length > 1) {
      validGroups.push(group);
    } else {
      ungroupedPoints.push(...group); // Flatten single-point groups into the ungrouped array
    }
  });

  // Return structure: [arrayOfValidGroups, arrayOfUngroupedPoints]
  return [validGroups, ungroupedPoints];
};
Step 4: Prepare for Scatter Plot Display

Since you want to show the point with the smallest Y value per group (and reveal the rest on click), we can transform the grouped data into a plot-ready format:

const preparePlotData = (processedData) => {
  const [groups, ungrouped] = processedData;
  
  // Process each valid group to get the display point (min Y) and all group points
  const groupPlotData = groups.map(group => {
    const minYPoint = group.reduce((min, point) => 
      point.coordinates.y < min.coordinates.y ? point : min, group[0]
    );
    return {
      displayPoint: minYPoint,
      allPoints: group
    };
  });

  // Add ungrouped points as individual display items
  const ungroupedPlotData = ungrouped.map(point => ({
    displayPoint: point,
    allPoints: [point]
  }));

  return [...groupPlotData, ...ungroupedPlotData];
};
Testing with Your Sample Data

Let's run this with your example data to see how it works:

const sampleData = [
  { otherData: "data1", coordinates: { x: 2022, y: 149832 } },
  { otherData: "data2", coordinates: { x: 2023, y: 153729 } },
  { otherData: "data3", coordinates: { x: 2024, y: 156800 } },
  { otherData: "data4", coordinates: { x: 2024, y: 195233 } },
  { otherData: "data5", coordinates: { x: 2035, y: 341978 } }
];

// Get grouped and ungrouped data
const processed = processDataForPlot(sampleData);
// Prepare data for plotting
const plotReadyData = preparePlotData(processed);

console.log(plotReadyData);

Output Explanation:

  • The first valid group includes points 1, 2, 3 (each adjacent X differs by 1, and Y differences are all under 10k)
  • Points 4 and 5 don't match any other points (X difference between 4 and 5 is 11, way over the 1-year limit), so they end up in the ungrouped array
  • The plot-ready data will have 3 display items: one for the first group (showing the 2022 point, since it has the smallest Y), and two individual items for points 4 and 5.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:43:12