【问题标题】:How can I map an array with duplicate values to a unique array in Javascript?如何将具有重复值的数组映射到 Javascript 中的唯一数组?
【发布时间】:2014-01-28 18:58:33
【问题描述】:

我有以下数组:

var tst = 
[
 {"topicId":1,"subTopicId":1,"topicName":"a","subTopicName":"w"},
 {"topicId":1,"subTopicId":2,"topicName":"b","subTopicName":"x"},
 {"topicId":1,"subTopicId":3,"topicName":"c","subTopicName":"y"},
 {"topicId":2,"subTopicId":4,"topicName":"c","subTopicName":"z"}
]

有没有一种简单的方法可以将它映射到这种类型的数组,其中 topicId > id 和 topicName > name:

var t = 
[
  {"id":1,"name":"a"},
  {"id":2,"name":"c"}
]

我使用的是现代浏览器,如果有帮助,我也有 _lodash。请注意,tst 数组中将有大约 100 行,因此我不需要非常优化的解决方案。一个简单且易于维护的解决方案将更为重要。

【问题讨论】:

  • 哇,我刚刚看了那个链接。非常多的代码。我想知道是否有更简单的 lodash 解决方案。
  • “topicId > id and topicName > name”是什么意思。 topicName 和 name 是字符串,不能大于或小于另一个..?

标签: javascript lodash


【解决方案1】:

最近的

_.uniqBy is now preferable

Full working example here

var tst = [
 {"topicId":1,"subTopicId":1,"topicName":"a","subTopicName1":"w"},
 {"topicId":2,"subTopicId":2,"topicName":"b","subTopicName2":"x"},
 {"topicId":3,"subTopicId":3,"topicName":"c","subTopicName3":"y"},
 {"topicId":1,"subTopicId":4,"topicName":"c","subTopicName4":"z"}
];

var result = _.map(_.uniqBy(tst, 'topicId'), function (item) {
    return {
        id: item.topicId,
        name: item.topicName
    };  
});

console.log(result);

遗留

http://lodash.com/docs#uniq 是一个好的开始

_.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');

您的代码将如下所示以获取唯一的主题 id

var t = _.uniq(tst, 'topicId');

编辑

我做了一个 jsfiddle

http://jsfiddle.net/q5HNw/

更新

删除了不必要的名称唯一性

http://jsfiddle.net/q5HNw/1/

【讨论】:

  • 你能给我一个使用我拥有的代码的例子吗?当我查看您的示例时,我不太确定如何更改字段名称。
  • 每个 topicID 的 topicName 总是相同的。那么这可以通过一个 _.uniq 检查变得更简单吗?
  • 是的,用_.uniq(t, 'name') 扔掉指令,我会更新我的答案和jsfiddle
  • 这无法识别唯一的主题名称?至少我的测试失败了。
  • @Melina 我想我误解了你的意思,你必须使用 uniq 来按 topicName 过滤,因为一个 id X 和一个名字 Y 的主题可能有一个 id W 但也有一个名字 Y
【解决方案2】:

我是那些使用原生函数的人之一 :)

var results = tst.reduce(function(res,topic){
var exists = res.some(function(t){ return (t.id === topic.topicId && t.name === topic.topicName);});        
     if (!exists){
        res.push({"id": topic.topicId, "name": topic.topicName});
     }
return res; },[]);

Lodash 版本

我不是使用 lodash 的专家,可能我会尝试这样的事情:

var results = _.reduce(tst, function(res, topic){       
    var exists = _.findIndex(res, function(t){
        return (t.id === topic.topicId && t.name === topic.topicName);
    });
    if (exists === -1){
      res.push({"id": topic.topicId, "name": topic.topicName});
    }
    return res; 
},[]);

【讨论】:

  • 但我已经将 lodash 用于其他用途。我想知道这是否会更容易,因为我拥有的记录数量很少,而且事实并非经常需要。只是想用 lodash 可能更容易维护。
  • @Melina 我将原帖翻译到 lodash
【解决方案3】:

使用 ECMAScript 2015 Array.prototype.find()

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。

let tst = [
     {"topicId":1,"subTopicId":1,"topicName":"a","subTopicName":"w"},
     {"topicId":1,"subTopicId":2,"topicName":"b","subTopicName":"x"},
     {"topicId":1,"subTopicId":3,"topicName":"c","subTopicName":"y"},
     {"topicId":2,"subTopicId":4,"topicName":"c","subTopicName":"z"},
];

let t = [];
tst.forEach(obj => {
  // Check if the id already exists in the array 't'
  if (!t.find((self) => self.id === obj.topicId)) {
    // If not, pushes obj to t
    t.push({
      id: obj.topicId,
      name: obj.topicName
    });
  }
});

console.log(t);

您还可以比较多个属性:

let tst = [
         {"topicId":1,"subTopicId":1,"topicName":"a","subTopicName":"w"},
         {"topicId":1,"subTopicId":2,"topicName":"b","subTopicName":"x"},
         {"topicId":1,"subTopicId":3,"topicName":"c","subTopicName":"y"},
         {"topicId":2,"subTopicId":4,"topicName":"c","subTopicName":"z"},
];


let t = [];
tst.forEach(obj => {
  // Check if the 'id' and 'subId' already exist in t 
  if (!t.find((self) => self.id === obj.topicId && self.subId === obj.subTopicId)) {
    // If not, pushes obj to t
    t.push({
      id: obj.topicId,
      subId: obj.subTopicId,
      name: obj.topicName
    });
  }
});

console.log(t);

【讨论】:

    猜你喜欢
    • 2019-08-25
    • 2019-03-24
    • 2023-01-19
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    相关资源
    最近更新 更多