【问题标题】:Javascript Replace item if key is duplicate and sort and delete except last 2 itemsJavascript 如果键是重复的,则替换项目并排序和删除,除了最后 2 个项目
【发布时间】:2019-05-08 20:38:26
【问题描述】:

我有如下数组,我想按键排序,然后删除除最后两项之外的所有内容并删除剩余的。

var status = new Array();
status.push({key: 'BOB', value: 10});
status.push({key: 'TOM', value: 3});
status.push({key: 'ROB', value: 22});
status.push({key: 'JON', value: 7});

如果我再次用重复键按下下面:

status.push({key: 'BOB', value: 20});

我需要以下输出,如何在 javascript 中实现。

[
  {
    "key": "BOB",
    "value": 20
  },
  {
    "key": "TOM",
    "value": 3
  },
  {
    "key": "ROB",
    "value": 22
  },
  {
    "key": "JON",
    "value": 7
  }
]

注意:我需要稍后按键排序。

编辑:如果我有这样的对象,我如何按键排序?并只获取​​最后 2 个项目并删除剩余的项目。

var status = new Object();
status['BOB'] = 10
status['TOM'] = 3
status['ROB'] = 22
status['JON'] = 7

【问题讨论】:

  • 为什么要使用数组而不是键为名称的对象?这将自动执行此操作。
  • 在推送新值之前,搜索数组以查看键是否已存在。如果是,请更换它。
  • 我想稍后按键排序,我想这在对象中是不可能的
  • @g.aziz 重复听起来很有希望,但答案并非如此。

标签: javascript arrays object


【解决方案1】:

我会使用Map 而不是数组或对象。地图就像对象but with some important differences

// initialize the map
var stats = new Map([['BOB',10],['TOM',3],['ROB',22],['JON',7]]);
// set a specific key's value
stats.set('BOB', 20);
// sort by key
var keys = Array.from(stats.keys());
keys.sort();
// get the last two
keys = keys.slice(-2);
// map the remaining keys to the desired structure
var result = keys.map(key => { 
  return { 
    key: key, 
    value: stats.get(key) 
  }; 
});
console.log(result);

【讨论】:

  • status map count 每次我使用 set 时都会增加,如果我使用 var stats 而不是 var result ,它会起作用吗?
  • @Graciewilliams 我不确定你的意思。我刚刚更新为使用变量名stats 而不是status 来解决window.status 问题。 result 变量仅保存新结构(具有键和值属性的对象数组)。
  • 我的意思是如果在 slice 之后再次执行 console.log(stats) ,它应该具有相同的结果内容......并再次重复使用它,因为我每秒获得 100 条数据,
  • 这个答案和其他答案一样,回答了提出的问题。如果您还有其他未在此问题中提及的要求,请提出一个新问题,并确保提前提及所有要求。
  • @dota2pro Map key equality algorithm 确保Map 中不存在重复键。它的价值是 exact same algorithm that Set uses
【解决方案2】:

不要使用数组,而是使用对象:

(function () {
  var status = {};
  status['BOB'] = 10;
  status['TOM'] = 3;
  status['ROB'] = 22;
  status['JON'] = 7;
  status['BOB'] = 20;
  // convert to array
  var output = Object.keys(status)
    // sort by key
    .sort()
    // keep last two after sorting
    .slice(-2)
    // convert [key, value] to { key, value }
    .map(function (key) {
      return { key: key, value: status[key] };
    });

  console.log(output);
})();
.as-console-wrapper{max-height:100%!important}

【讨论】:

  • 谢谢你的工作顺利,我如何在排序后删除除最后 2 个以外的所有内容?
  • 看@Triptych 的回答,他整理好了
  • @Graciewilliams 请参阅Object.keysfor...in,最后是delete。他的回答是错误的。如果您想要保证键的迭代顺序,请使用Map,而不是对象。
  • 我使用了类似 myObject.set('@', 2); ,但我在 ajax 请求中随机推送项目,所以无法按顺序推送,我必须稍后对其进行排序,然后删除除最后两项之外的项目。
  • @Graciewilliams 更好?
【解决方案3】:

如果您决定保留对象数组结构,您可以使用Array.findIndex()Array.splice() 以这种方式实现一个方法:

const pushWithCheck = (arr, obj) =>
{
    let idx = arr.findIndex(({key}) => key === obj.key);

    if (idx >= 0)
        arr.splice(idx, 1, obj);
    else
        arr.push(obj);
}

var _status = [];
pushWithCheck(_status, {key: 'BOB', value: 10});
pushWithCheck(_status, {key: 'TOM', value: 3});
pushWithCheck(_status, {key: 'ROB', value: 22});
pushWithCheck(_status, {key: 'JON', value: 7});
console.log("Before duplicated key:", _status);
pushWithCheck(_status, {key: 'BOB', value: 20});
pushWithCheck(_status, {key: 'ROB', value: 99});
console.log("After duplicated key:", _status);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

现在,要按对象的 key 属性排序并获取最后一个 2 元素,您可以将 Array.sort()Array.slice() 与否定 (-2) 参数一起使用,如下所示:

const pushWithCheck = (arr, obj) =>
{
    let idx = arr.findIndex(({key}) => key === obj.key);

    if (idx >= 0)
        arr.splice(idx, 1, obj);
    else
        arr.push(obj);
}

// Generate the _status array.
var _status = [];
pushWithCheck(_status, {key: 'BOB', value: 10});
pushWithCheck(_status, {key: 'TOM', value: 3});
pushWithCheck(_status, {key: 'ROB', value: 22});
pushWithCheck(_status, {key: 'JON', value: 7});
pushWithCheck(_status, {key: 'BOB', value: 20});
pushWithCheck(_status, {key: 'ROB', value: 99});
console.log("_status is: ", _status);

// Sort the _status array by ascending.
let sorted = _status.slice().sort((a, b) => a.key.localeCompare(b.key));

// Get last two elements of the sorted array.
let lastTwo = sorted.slice(-2);

console.log("Sorted is: ", sorted);
console.log("Last two elements are: ", lastTwo);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

【讨论】:

    【解决方案4】:

    如果您想按照其他人建议的方式进行操作,您应该使用 set 集合中始终包含唯一元素

    // initialize the map
    var stats = new Set([['BOB',10],['TOM',3],['ROB',22],['JON',7]]);
    // set a specific key's value
    stats.add('BOB', 20);
    // sort by key
    var keys = Array.from(stats.keys());
    keys.sort();
    // get the last two
    keys = keys.slice(-2);
    // map the remaining keys to the desired structure
    var result = keys
    console.log(result);

    我认为这回答了你所有的问题

    let status1 = [];
    status1.push({
        key: 'BOB',
        value: 10
    }, {
        key: 'TOM',
        value: 3
    }, {
        key: 'ROB',
        value: 22
    }, {
        key: 'JON',
        value: 7
    });
    
    console.log('Initial array', status1);
    
    //const newItem = {
    //  key: 'BOB',
    //  value: 20
    //};
    
    const newItem = {
        key: 'BOB',
        value: 99
    };
    
    for (let i = 0; i < status1.length; i++) {
    
        if (status1[i].key === newItem.key) {
            status1[i] = newItem;
        }
    
    }
    
    Array.prototype.inArray = function(comparer) { 
        for(var i=0; i < this.length; i++) { 
            if(comparer(this[i])) return true; 
        }
        return false; 
    }; 
    Array.prototype.pushIfNotExist = function(element, comparer) { 
        if (!this.inArray(comparer)) {
            this.push(element);
        }
    }; 
    
    //https://stackoverflow.com/questions/1988349/array-push-if-does-not-exist 
    
    status1.pushIfNotExist(newItem, function(e) { 
        return e.key === newItem.key; 
    });
    
    console.log('after push', status1);
    
    function sortByKey(array, key) {
        return array.sort(function (a, b) {
            var x = a[key];
            var y = b[key];
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        });
    }
    
    sortByKey(status1, 'key');
    console.log('AFter sort', status1);
    
    console.log('Last item', status1[status1.length - 1]);
    console.log('Second Last item', status1[status1.length - 2]);

    【讨论】:

    • 好的,如果我推送一些不存在的东西怎么办?我觉得你没有条件
    • 添加 if (status1["key"] === undefined) { // 如果不存在
    • status1["key"] === undefined总是为真。如果您要将BOT 改回BOB,那么您将替换第一个条目并使用相同的键添加一个新条目。
    • 现在你正在修改数组原型,它只是打开了一个完全不同的蠕虫罐......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 2022-08-05
    • 1970-01-01
    相关资源
    最近更新 更多