【问题标题】:Javascript: Remove duplicates in array of objects using a single propertyJavascript:使用单个属性删除对象数组中的重复项
【发布时间】:2020-07-15 21:15:32
【问题描述】:

我有这样的对象,其中“id”是唯一的。我需要从低于 ES5 的任何版本的 javascript 中的对象数组中删除重复项。我需要根据 id 字段进行比较并删除其重复项。

例子:

Object = [
{id: id_one, value: value_one, label: ABC},
{id: id_one, value: value_one, label: ABC},
{id: id_three, value: value_three, label: ABX},
{id: id_two, value: value_two, label: ABY},
{id: id_four, value: value_four, label: ABD}
];

输出:

result = [
{id: id_one, value: value_one, label: ABC},
{id: id_three, value: value_three, label: ABX},
{id: id_two, value: value_two, label: ABY},
{id: id_four, value: value_four, label: ABD}
];

我试过这样的逻辑,

function getDistValues(object) {
  var distObject = [];
  var tempIndex = [];
  var length = object.length;

  for (var i = 0; i < length; i++) {
    tempIndex.push(object[i].id);

    if (tempIndex.indexOf(object[i].id) === -1 || i === 0) {
      distObject.push(object[i]);
    }
  }

  return distObject;
}

它只给出第一个对象。我尝试映射 ID 并进行比较,但没有成功。

任何帮助都会对我有用。

【问题讨论】:

  • 在检查tempIndex.indexOf(object[i].id) 之前,您总是先做tempIndex.push(object[i].id);,显然它总是会找到。另外,你能从我这里得到的最好的结果是从 ES2017 解决方案到 ES3 的 babel transpile,因为实际上,这些天谁在编写 ES3?!

标签: javascript object duplicates


【解决方案1】:

这是因为你总是将id添加到tempIndex数组中,所以它总是认为当前的id是重复的。试试:

function getDistValues(object) {
  var distObject = [];
  var tempIndex = [];
  var length = object.length;

  for (var i = 0; i < length; i++) {    
    if (tempIndex.indexOf(object[i].id) === -1 || i === 0) {
      tempIndex.push(object[i].id);
      distObject.push(object[i]);
    }
  }

  return distObject;
}

【讨论】:

    【解决方案2】:

    如果id 不在集合中,您可以将Set 用于id 属性并过滤。

    var array = [{ id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_three', value: 'value_three', label: 'ABX' }, { id: 'id_two', value: 'value_two', label: 'ABY' }, { id: 'id_four', value: 'value_four', label: 'ABD' }],
        unique = array.filter((ids => ({ id }) => !ids.has(id) && ids.add(id))(new Set));
    
    console.log(unique);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    旧 JS 版本的方法

    var array = [{ id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_three', value: 'value_three', label: 'ABX' }, { id: 'id_two', value: 'value_two', label: 'ABY' }, { id: 'id_four', value: 'value_four', label: 'ABD' }],
        ids = {},
        unique = [],
        i;
    
    for (i = 0; i < array.length; i++) {
        if (ids[array[i].id]) continue;
        unique.push(array[i]);
        ids[array[i].id] = true;
    }
    
    console.log(unique);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案3】:

      您可以通过将id 存储到object 中并检查id 是否已存在于object 中来实现。如果存在,则表示您之前已经拿过该对象。如果没有,则将对象推送到新数组中。

      这种方法需要O(n) 时间,因为我们检查一个具有恒定时间的对象。

      var arr = [
          {id: 'id_one', value: 'value_one', label: 'ABC'},
          {id: 'id_one', value: 'value_one', label: 'ABC'},
          {id: 'id_three', value: 'value_three', label: 'ABX'},
          {id: 'id_two', value: 'value_two', label: 'ABY'},
          {id: 'id_four', value: 'value_four', label: 'ABD'}
      ];
      
      
      function getDistValues(arr) {
      	var hash = {};
          var uniqueArr = [];
          
      	for (var i = 0, l = arr.length; i < l; i++) {
          	    if (hash[arr[i].id] === undefined) {
              	hash[arr[i].id] = 1;
                      uniqueArr.push(arr[i]);
                  }	
              }
          
          return uniqueArr;
      }
      
      console.log(getDistValues(arr));
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

        【解决方案4】:

        您可以使用reduce() 方法对数组使用Object.values 过滤重复项

        const inputArray = [
            {id: 'id_one', value: 'value_one', label: 'ABC'},
            {id: 'id_one', value: 'value_one', label: 'ABC'},
            {id: 'id_three', value: 'value_three', label: 'ABX'},
            {id: 'id_two', value: 'value_two', label: 'ABY'},
            {id: 'id_four', value: 'value_four', label: 'ABD'}
            ]
        
        
              
        const filterArray = (arr) => Object.values(arr.reduce(
          (acum, item) => {
            acum[item.id] = item
            return acum
          }, 
          {})
        )
        
        console.log(filterArray(inputArray))

        【讨论】:

          【解决方案5】:

          您正在将项目添加到tempIndex 数组之前您检查它们是否存在。由于您总是添加每一个,因此当您进行检查时,这意味着该项目已经存在。

          你必须反过来 - 检查一个项目是否存在然后将它添加到tempIndex

          var data = [
            {id: "id_one", value: "value_one", label: "ABC"},
            {id: "id_one", value: "value_one", label: "ABC"},
            {id: "id_three", value: "value_three", label: "ABX"},
            {id: "id_two", value: "value_two", label: "ABY"},
            {id: "id_four", value: "value_four", label: "ABD"}
          ];
          
          function getDistValues(object) {
            var distObject = [];
            var tempIndex = [];
            var length = object.length;
          
            for (var i = 0; i < length; i++) {
              //check first
              var notSeen = tempIndex.indexOf(object[i].id) === -1;
              
              if (notSeen) {
                tempIndex.push(object[i].id);
                //add later
                distObject.push(object[i]);
              }
            }
          
            return distObject;
          }
          
          var result = getDistValues(data);
          
          console.log(result);

          为了更高效,您还可以使用一个对象来保留重复的 ID - 这将消除对 tempIndex 每次循环的另一次迭代的需要:

          var data = [
            {id: "id_one", value: "value_one", label: "ABC"},
            {id: "id_one", value: "value_one", label: "ABC"},
            {id: "id_three", value: "value_three", label: "ABX"},
            {id: "id_two", value: "value_two", label: "ABY"},
            {id: "id_four", value: "value_four", label: "ABD"}
          ];
          
          function getDistValues(object) {
            var distObject = [];
            //use object
            var tempIndex = {};
            var length = object.length;
          
            for (var i = 0; i < length; i++) {
              var notSeen = tempIndex[object[i].id] !== true;
              
              if (notSeen) {
                //mark as visited
                tempIndex[object[i].id] = true;
                distObject.push(object[i]);
              }
            }
          
            return distObject;
          }
          
          var result = getDistValues(data);
          
          console.log(result);

          【讨论】:

          • 我觉得很有趣,当exists 为真时,它不存在(未找到)。
          猜你喜欢
          • 2015-12-14
          • 1970-01-01
          • 2018-03-28
          • 1970-01-01
          • 1970-01-01
          • 2016-07-02
          • 1970-01-01
          • 1970-01-01
          • 2012-05-17
          相关资源
          最近更新 更多