【问题标题】:NodeJS: Extracting duplicates from ArrayNodeJS:从数组中提取重复项
【发布时间】:2018-06-27 18:18:24
【问题描述】:

我需要你的帮助...如果问题已经被问过,但我似乎无法找到适合我的问题的答案,我很抱歉:我正在尝试提取(而不是删除) 我的数组中的重复项列表。

最终,主要目标是只保留一个重复的对象(在数组中)具有更高的利润......

这是我的数组的一个简单示例:

var arr = [
  {
    mkBase: "test",
    mkComp: "test1",
    invest: { profit: 10 },
    availability: true,
    option: 1
  },
  {
    mkBase: "test",
    mkComp: "test1",
    invest: { profit: 15 },
    availability: false,
    option: 2
  },
  {
    mkBase: "test1",
    mkComp: "test",
    invest: { profit: 8 },
    availability: true,
    option: 3
  },
  {
    mkBase: "test2",
    mkComp: "test",
    invest: { profit: 6 },
    availability: true,
    option: 4
  },
  {
    mkBase: "test",
    mkComp: "test2",
    invest: { profit: 6 },
    availability: true,
    option: 5
  },
  {
    mkBase: "test",
    mkComp: "test3",
    invest: { profit: 7 },
    availability: true,
    option: 6
  },
  {
    mkBase: "test",
    mkComp: "test3",
    invest: { profit: 10 },
    availability: true,
    option: 7
  },
  {
    mkBase: "test3",
    mkComp: "test4",
    invest: { profit: 10 },
    availability: true,
    option: 8
  }
];

我设法提取了几乎所有重复项的列表:

for (var i = 0; i < arr.length; i++) {
  if (_.uniqBy(arr, "mkBase").indexOf(arr[i]) == -1) {
    console.log("[SAME BASE]: " + JSON.stringify(arr[i], null, 2));
  } else if (_.uniqBy(arr, "mkComp").indexOf(arr[i]) == -1) {
    console.log("[SAME COMP]: " + JSON.stringify(arr[i], null, 2));
  }
}

结果如下:

[SAME BASE]: {
  "mkBase": "test",
  "mkComp": "test1",
  "invest": {
    "profit": 15
  },
  "availability": false,
  "option": 2
}
[SAME COMP]: {
  "mkBase": "test2",
  "mkComp": "test",
  "invest": {
    "profit": 6
  },
  "availability": true,
  "option": 4
}
[SAME BASE]: {
  "mkBase": "test",
  "mkComp": "test2",
  "invest": {
    "profit": 6
  },
  "availability": true,
  "option": 5
}
[SAME BASE]: {
  "mkBase": "test",
  "mkComp": "test3",
  "invest": {
    "profit": 7
  },
  "availability": true,
  "option": 6
}
[SAME BASE]: {
  "mkBase": "test",
  "mkComp": "test3",
  "invest": {
    "profit": 10
  },
  "availability": true,
  "option": 7
}

Lodash 方法 (_.uniqBy) 将其中一个副本保留在主数组中,并且,为了最终获得最好的副本 (_.maxBy(arr, 'profit')),我会需要它其他副本。

我不确定我是否很清楚,但如果您需要任何澄清,请告诉我!

提前感谢大家!

********** 编辑 ************* 正如 stasovlas 所建议的,您会在预期结果下方找到数组中其他对象被删除的原因:

var result = [
  {
    mkBase: "test",
    mkComp: "test1",
    invest: { profit: 15 },
    availability: false,
    option: 2
  },
  {
    mkBase: "test1",
    mkComp: "test",
    invest: { profit: 8 },
    availability: true,
    option: 3
  },
  {
    mkBase: "test3",
    mkComp: "test4",
    invest: { profit: 10 },
    availability: true,
    option: 8
  }
];

var removed = [
  //Reason: Same Base **and** Comp mk as option 2 && Profit is too low versus option 2
  {
    mkBase: "test",
    mkComp: "test1",
    invest: { profit: 10 },
    availability: true,
    option: 1
  },
  //Reason: Same Comp mk as option 3 && Profit is too low versus option 3
  {
    mkBase: "test2",
    mkComp: "test",
    invest: { profit: 6 },
    availability: true,
    option: 4
    //Reason: Same Base mk as option 2 && Profit is too low versus option 2
  },
  {
    mkBase: "test",
    mkComp: "test2",
    invest: { profit: 6 },
    availability: true,
    option: 5
  },
  //Reason: Same Base mk as option 2 && Profit is too low versus option 2 
  {
    mkBase: "test",
    mkComp: "test3",
    invest: { profit: 7 },
    availability: true,
    option: 6
  },
  //Reason: Same Base mk as option 2 && Profit is too low versus option 2 
  {
    mkBase: "test",
    mkComp: "test3",
    invest: { profit: 10 },
    availability: true,
    option: 7
  }
];

【问题讨论】:

  • 您的应用中是否需要随时重复的项目?你可能想看看这个关于数据结构的线程:“当你真正需要一个集合时不要使用数组”:stackoverflow.com/questions/40055764/…我知道上下文是 Firebase,但你可能会在那里找到答案
  • 谢谢,我会调查它,但我对 Firebase 一点也不熟悉。为了回答你的问题,不,我以后不需要它......一旦我选择了具有最高利润值的对象(从副本中),我基本上把其他的都扔掉了。
  • 很高兴有帮助。 Firebase 是一个不同的主题,但它在这里提供的答案可能是对数据结构的一个很好的反思(我的意思是,它让我对数据结构和我们都有的习惯有了不同的看法)看看这个答案是你在找什么顺便说一句:stackoverflow.com/questions/16747798/…

标签: arrays node.js duplicates filtering lodash


【解决方案1】:

我不确定我的问题理解,但这里是我的解决方案:

const res = _.reduce(arr, (result, item) => {
    const same = _.find(result, r => _.some([
        r.mkBase === item.mkBase,
        r.mkComp === item.mkComp
    ])); // find same already added item

    if (same === undefined) {
        return _.concat(result, item); // just push item   
    }

    if (same.invest.profit >= item.invest.profit) {
        return result; // do nothing if profit is less then already added
    }

    return _.chain(result) // remove item with smaller profit and push item with higher profit
        .reject({ mkBase: same.mkBase, mkComp: same.mkComp })
        .concat(item)
        .value();
}, []);

【讨论】:

  • 嘿@stasovlas!感谢您的回答,但不幸的是,最终我希望摆脱所有重复项,只保留最高利润的那个。例如:我不能作为基础:“测试”以“test2”作为补偿,另一个以基础“test3”和“test2”作为补偿。就像我不能将“test”作为基础,将“test2”作为comp,然后再将“test and comp”test3”作为基础......对不起,我担心这不是很清楚!但是让我知道我可以如何帮助澄清事情......
  • @Ardzii 你能在你的问题中添加预期的结果吗?
  • 完成!感谢 stasovlas 提出这个建议! :)
  • 这似乎成功了!谢了哥们!我需要了解您的答案才能立即应用它!我会及时向大家发布!再次感谢!
  • @Ardzii 呵呵,我的英文不好解释,希望这篇文章对你有帮助medium.freecodecamp.org/reduce-f47a7da511a9
【解决方案2】:
var sameBase = {}, sameComp = {};

arr.forEach(item => {
    let existingBase = sameBase[item.mkBase];

    if ( ( existingBase === undefined ) ||  ( existingBase.invest.profit < item.invest.profit ) ) {
            sameBase[item.mkBase] = item;  
    } 

    existingComp = sameComp[item.mkComp];
    if ( ( existingComp === undefined ) ||  ( existingComp.invest.profit < item.invest.profit ) ) {
        sameComp[item.mkComp] = item;  
    }
});

var sameBaseArr = toArr(sameBase);
var sameCompArr = toArr(sameComp);

console.log("SAME BASE: " + JSON.stringify(sameBaseArr, true));
console.log("SAME COMP: " + JSON.stringify(sameCompArr, true));

function toArr(map) {
    let arr = [];
    for (var key in map) {
        arr.push(map[key]);
    }   
    return arr;     
}

【讨论】:

  • 嘿科夫曼!我认为你有一些东西......不过我需要结合你的两个功能!让我检查其他人的答案并尝试结合,我会回到你身边!谢谢!
  • 基于您要结合的标准?你需要只连接两个数组吗?或者,根据一些平等标准进一步去重?例如。 obj1 等于 obj2 当且仅当 obj1.mkBase 等于 obj2.mkComp? - 类似的东西?需要更多信息...
  • Kofman 完全没问题,感谢您的跟进...我需要删除重复项,无论是重复的 mkBase 还是 mkComp,即。我只需要保留一个唯一的 mkBase 对象和一个唯一的 mkComp 对象,而我保留的对象必须是利润最高的对象。另外,如果在数组 (arr) 中有非重复对象(没有其他 mkBase 或 mkComp(与选项 8 一样),我需要保留它们。我希望这可以澄清事情!再次感谢!:P
【解决方案3】:

试试这个(未经测试,但逻辑可以提供帮助):

var mkBases = [], mkComps = [];

for (var i = 0; i < arr.length; i++) {
    var actualBase = arr[i].mkBase;
    var actualComp = arr[i].mkComp;

    if (typeof mkBases[actualBase] !== 'undefined') {
        mkBases[actualBase] = {getAllIndexes(arr, actualBase)}
    }

    if (typeof mkComps[actualComp] !== 'undefined') {
        mkComps[actualComp] = {getAllIndexes(arr, actualComp)}
    }
}

function getAllIndexes(arr, val) {
    var indexes = [], i = -1;
    while ((i = arr.indexOf(val, i+1)) != -1){
        indexes.push(i);
    }
    return indexes;
}

现在您可以遍历 mkBases 和 mkComp 来获取您的副本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    • 2012-10-07
    • 2014-07-01
    • 1970-01-01
    • 2018-02-11
    • 2018-10-13
    • 1970-01-01
    相关资源
    最近更新 更多