【问题标题】:Reduce 1D list into jagged 2D list based on duplicate dictionary properties基于重复字典属性将一维列表减少为锯齿状二维列表
【发布时间】:2021-11-09 04:52:25
【问题描述】:

我有一个这样的字典列表,其中可能包含基于一些字典属性(不是所有属性)的重复项:

const data = [{
  name: 'v',
  latitude: '30.0',
  longitude: '25.0'
}, {
  name: 'w',
  latitude: '30.0',
  longitude: '25.0'
}, {
  name: 'x',
  latitude: '45.9',
  longitude: '50.2'
}, {
  name: 'y',
  latitude: '40.5',
  longitude: '85.7'
}, {
  name: 'z',
  latitude: '40.5',
  longitude: '85.7'
}];

在这里,如果两个字典具有相同的经度和纬度,则它们被视为重复。

目标是减少这个一维列表,将一种类型的所有重复项分组到一个嵌套列表中。例如,如果我们有三个具有相同坐标的副本,它们应该进入自己的嵌套列表,而另一个坐标的两个副本进入不同的嵌套列表。即使是没有重复的独立坐标也应该进入它自己的嵌套列表。我们希望最终得到一个列表,其中每个项目都是一个表示唯一坐标的列表。

期望的输出:

[
  [
    {
      name: 'v',
      latitude: '30.0',
      longitude: '25.0'
     }, {
      name: 'w',
      latitude: '30.0',
      longitude: '25.0'
    }
  ], 
  [
    {
      name: 'x',
      latitude: '45.9',
      longitude: '50.2'
    }
  ],
  [
    {
      name: 'y',
      latitude: '40.5',
      longitude: '85.7'
    }, {
      name: 'z',
      latitude: '40.5',
      longitude: '85.7'
    }
  ]
];

编辑:更正了所需的输出,以便所有项目都是列表。

【问题讨论】:

    标签: javascript arrays reduce


    【解决方案1】:

    我首先将每个数据点放入一个对象中。我会使用坐标 (lat,lng) 作为指向每个唯一坐标的数组的键。当您遍历数据点时,您可以将每个数据点添加到对象中的相应数组中。

    然后遍历您刚刚创建的对象的值。每个值都应该是一个数组。如果该数组的长度为 1,则可以将对象添加到输出数组中,但如果大于 1,则可以将整个数组添加到输出数组中。

    瞧。

    const data = [{
      name: 'v',
      latitude: '30.0',
      longitude: '25.0'
    }, {
      name: 'w',
      latitude: '30.0',
      longitude: '25.0'
    }, {
      name: 'x',
      latitude: '45.9',
      longitude: '50.2'
    }, {
      name: 'y',
      latitude: '40.5',
      longitude: '85.7'
    }, {
      name: 'z',
      latitude: '40.5',
      longitude: '85.7'
    }];
    
    let obj = {};
    data.forEach(e => {
      let key = `${e.latitude},${e.longitude}`;
      if(obj[key] == undefined)
        obj[key] = [];
      obj[key].push(e);
    });
    
    let output = [];
    Object.values(obj).forEach(e => {
      if(e.length == 1)
        output.push(e[0]);
      else
        output.push(e);
    });
    
    console.log(output);

    【讨论】:

    • 更正了我想要的输出,以便所有项目都是列表
    【解决方案2】:

    虽然有很多选择,但我更喜欢使用 reduce 的解决方案。

    基本上,我们使用不同的latitudelongitude 作为键来构建一个对象,以获得唯一的键,如果重复,我们创建一个数组(如果之前没有创建),然后推送该项目。

    我认为这对您的目的来说非常优雅易读和高效。

    注意:根据用户要求,已更正为将所有内容都放在数组中。

    const data = [{
      name: 'v',
      latitude: '30.0',
      longitude: '25.0'
    }, {
      name: 'w',
      latitude: '30.0',
      longitude: '25.0'
    }, {
      name: 'x',
      latitude: '45.9',
      longitude: '50.2'
    }, {
      name: 'y',
      latitude: '40.5',
      longitude: '85.7'
    }, {
      name: 'z',
      latitude: '40.5',
      longitude: '85.7'
    }];
    
    
    const reducer = (accum, cv, i) => {
      // create a key using the lat and lng
      const key = `${cv.latitude}-${cv.longitude}`;
    
      // if the key was already there, we need to push it.
      if (accum[key]) {
        accum[key] = [...accum[key], cv]
      } else {
        // if not, we just create an array with the entry
        accum[key] = [cv];
      }
      return accum;
    
    };
    
    const objectMapped = data.reduce(reducer, {});
    // then we get an object, to get the values we use this function.
    const result = Object.values(objectMapped);
    
    console.log(result);

    【讨论】:

    • 更正了我想要的输出,以便所有项目都是列表
    • @brienna 那样更容易,因为我们不需要检查它是对象还是数组,代码会更新。
    【解决方案3】:

    你可以这样做:

    const data = [{ name: 'v', latitude: '30.0', longitude: '25.0' },{ name: 'w', latitude: '30.0', longitude: '25.0' },{ name: 'x', latitude: '45.9', longitude: '50.2' },{ name: 'y', latitude: '40.5', longitude: '85.7' },{ name: 'z', latitude: '40.5', longitude: '85.7' },]
    
    const result = Object.values(data.reduce((a, c) => {
      const k = `${c.latitude}${c.longitude}`
      return (a[k] = [...(a[k] || []), c], a)
    }, {}))
    
    console.log(result)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 2014-04-21
      • 2015-01-30
      • 2012-04-10
      • 2023-02-19
      相关资源
      最近更新 更多