【问题标题】:Distinct value from the javascript array of object对象的 javascript 数组中的不同值
【发布时间】:2013-05-30 07:18:02
【问题描述】:

我确实有这种东西

var j = [{'one':1},{'two':2},{'three':3},{'four':4},{'five':5},{'one':1}];

现在我想跳过重复记录。谁能给我建议?

【问题讨论】:

  • @Samson 感谢您的审查..但它是一个数组。我有对象数组
  • 请查看link
  • @djtechie 对,现在您需要一种比较对象的方法。 Object.toJSON(obj) 会有所帮助。

标签: javascript jquery


【解决方案1】:

过滤出具有多个属性的对象的通用解决方案。

var list = [{'one':1},{'two':2},{'four':4},{'one':1},{'four':4},{'three':3},{'four':4},{'one':1},{'five':5},{'one':1}];


Array.prototype.uniqueObjects = function(){
    function compare(a, b){
        for(var prop in a){
            if(a[prop] != b[prop]){
                return false;
            }
        }
        return true;
    }
    return this.filter(function(item, index, list){
        for(var i=0; i<index;i++){
            if(compare(item,list[i])){
                return false;
            }
        }
        return true;
    });
}

var unique = list.uniqueObjects();

编辑:

无法比较第一个或第二个属性,因为对象的属性在 javascript 中不按顺序排列。我们可以做的是使用属性进行比较。

Array.prototype.uniqueObjects = function (props) {
    function compare(a, b) {
      var prop;
        if (props) {
            for (var j = 0; j < props.length; j++) {
              prop = props[j];
                if (a[prop] != b[prop]) {
                    return false;
                }
            }
        } else {
            for (prop in a) {
                if (a[prop] != b[prop]) {
                    return false;
                }
            }

        }
        return true;
    }
    return this.filter(function (item, index, list) {
        for (var i = 0; i < index; i++) {
            if (compare(item, list[i])) {
                return false;
            }
        }
        return true;
    });
};

var uniqueName = list.uniqueObjects(["name"]);
var uniqueAge = list.uniqueObjects(["age"]);
var uniqueObject = list.uniqueObjects(["name", "age"]);

http://jsbin.com/ahijex/4/edit

【讨论】:

  • 感谢tracevipin ..它真的有帮助:)。但是,如果我想通过特定领域,有什么办法吗?就像对象有两个键值,我只想匹配每个对象的第二个键值?
  • @djtechie 请记住 Array.filter() 方法仅在 ECMAScript 5 中可用。您唯一需要担心没有此功能的浏览器是 IE 8 及以下版本。
  • 我们可以将 indexOf 用于数组,那么对象是什么?
  • @djtechie 如果你想在这里过滤功能可以替换为 for 循环导致嵌套循环。对象键未在 Javascript 中编制索引。通过 ECMA 标准键应该按照它们添加到对象的顺序进行索引。但我们不能依赖这一点,因为并非所有浏览器都支持这种行为。
【解决方案2】:

1) 在数组中循环。
2) 在该循环中,循环遍历对象
3) 将密钥保存在全局变量中
4) 如果键已经存在,则从数组中删除对象。

但是,创建一个对象数组而不是一个大对象有什么意义呢?然后任何重复的键都会被自动覆盖...

喜欢

{
  "one" : 1,
  "two" : 2
  ...
}

【讨论】:

  • 我从 API 获取该数组,但无法更改输出格式 :) 这就是原因。你能给我一个解释的示例代码吗?
【解决方案3】:

你可以这样做:

var j = [{'one':1},{'two':2},{'three':3},{'four':4},{'five':5},{'one':1}];
var keyarr = [];
var unique = [];

j.map(function(obj, index) {
    for(var key in obj ) {
        console.log( key );
        if( $.inArray(key, keyarr) < 0 ) {
            var newobj = {};
            newobj[key] = obj[key];
            unique.push(newobj)
        }
    }
});
console.log( unique );

演示jsfiddle

【讨论】:

    【解决方案4】:

    您可以使用“地图”又名对象来跟踪不同的对象。假设唯一性由 keyvalue 相同。

    var data = [{'one':1},{'two':2},{'three':3},{'four':4},{'five':5},{'one':1}];
    var tempMap = {};    // keep track of unique objects with key mapping to the object's key&value
    var distinct = [];    // resulting list containing only unique objects
    var obj = null;
    for (var i = 0; i < data.length; i++) {
        obj = data[i];
        for (var key in obj) {        // look in the object eg. {'one':1}
            if (obj.hasOwnProperty(key)) {
                if (!tempMap.hasOwnProperty(key + obj[key])) {    // not in map
                    tempMap[key + obj[key]] = obj;        // then add it to map
                    distinct.push(obj);    // add it to our list of distinct objects
                }
                break;
            }
        }
    }
    console.log(distinct);   // list of distinct objects
    

    见小提琴:http://jsfiddle.net/amyamy86/saSqt/

    【讨论】:

      【解决方案5】:

      也试试这个:

      var j = [{'one':1},{'two':2},{'three':3},{'four':4},{'five':5},{'one':1}],
      d = [],
      key = [];
      d = j.slice(0);
      function getKeys(obj) {
          var r = []
          for (var k in obj) {
              if (!obj.hasOwnProperty(k)) 
                  continue
              r.push(k)
          }
          return r
      }
      for(var i=0; i< d.length; i++){
          key.push(getKeys(d[i]));
      }
      
      for(var kI = 0; kI < key.length; kI++){
          for(var kJ = 0; kJ < key.length; kJ++){
              if(kI !== kJ && key[kI][0] === key[kJ][0]){
                  key.splice(kJ,1);     
                  d.splice(kJ,1);
              }
          }
      }
      console.log(j);
      console.log(d);
      

      Working fiddle

      【讨论】:

        【解决方案6】:

        查看适用于 JavaScript 的 Linq (linq.js),这是 CodePlex 提供的免费 JavaScript 库:

        https://linqjs.codeplex.com/

        您可以在参考页面试用代码sn-ps live(包含在linqpad包中,先解压缩-然后将代码sn-p粘贴到代码框中,然后显示结果立即):

        LinqJS\linq.js_ver2.2.0.2\reference.htm

        与 C# LINQ 一样,它有一个 .distinct 方法,可以将您的 JSON 数组作为单行来完成这项工作,例如:

        var array = [100, 200, 30, 40, 500, 40, 200];
        var ex1 = Enumerable.From(array).Distinct().ToArray(); // [100, 200, 30, 40, 500]
        

        它具有您从 C# LINQ 中知道的大多数方法,并且可以作为非 jQuery 或作为具有完整 NUGET 支持的 jQuery 版本提供。

        也支持具有命名属性的数组,例如您在示例中的属性,例如:

        var list = [
               { one: 2, two: 4, three: 1 },
               { one: 4, two: 7, three: 5 },
               { one: 2, two: 4, three: 1 },
               { one: 7, two: 3, three: 2 },
               ];
        Enumerable.From(list).Distinct("$.one")
        .OrderBy("$.a").ThenBy("$.two").ThenBy("$.three")
        .Select("$.one + ':' + $.two + ':' + $.three")
        

        给你结果:

        2:4:1
        4:7:5
        7:3:2

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-08
          • 1970-01-01
          • 2013-02-14
          • 2021-06-07
          • 1970-01-01
          • 1970-01-01
          • 2019-05-25
          • 2017-09-26
          相关资源
          最近更新 更多