Javascript 通过对象数组中的值为对象指定列组

Javascript 通过对象数组中的值为对象指定列组,javascript,arrays,sorting,lodash,ranking,Javascript,Arrays,Sorting,Lodash,Ranking,我有一个这样的对象数组: var data = { a: [ { keyone:'c', keytwo: 'anna', keythree: 21, keyfour: 15 }, { keyone:'a', keytwo: 'anna', keythree: 22, keyfour: 15 }, { keyone:'s', keytwo: 'anna', keythree: 10, keyfour: 15 }, { keyo

我有一个这样的对象数组:

var data = {
    a: [
        { keyone:'c', keytwo: 'anna', keythree: 21, keyfour: 15 },
        { keyone:'a', keytwo: 'anna', keythree: 22, keyfour: 15 },
        { keyone:'s', keytwo: 'anna', keythree: 10, keyfour: 15 },
        { keyone:'v', keytwo: 'anna', keythree: 7, keyfour: 15 }
    ],

    b: [
        { keyone:'f', keytwo: 'any', keythree: 45, keyfour: 100 },
        { keyone:'b', keytwo: 'any', keythree: 146, keyfour: 100 },
        { keyone:'t', keytwo: 'any', keythree: 23, keyfour: 100 },
        { keyone:'h', keytwo: 'any', keythree: 11, keyfour: 100 }
    ]
  };
我想根据组内以及整个数据集中的
keytree
keytree
的值为每个对象分配等级。我该怎么做

更新:我已经在上面的代码中描述了等级

结果对象:

var data = {
    a: [
        { keyone:'c', keytwo: 'anna', keythree: 21, keyfour: 15, rankgroup: 3, rankall: 4 },

        { keyone:'a', keytwo: 'anna', keythree: 22, keyfour: 15, rankgroup: 4, rankall: 5 },

        { keyone:'s', keytwo: 'anna', keythree: 22, keyfour: 15, rankgroup: 2, rankall: 2 },

        { keyone:'v', keytwo: 'anna', keythree: 7, keyfour: 15, rankgroup: 1, rankall: 1 }
    ],

    b: [
        { keyone:'f', keytwo: 'any', keythree: 45, keyfour: 100 },

        { keyone:'b', keytwo: 'any', keythree: 146, keyfour: 100 },

        { keyone:'t', keytwo: 'any', keythree: 23, keyfour: 100 },

        { keyone:'h', keytwo: 'any', keythree: 11, keyfour: 100 }
    ]
};
我使用的是
lodash
。我的想法是首先根据这些键对数组进行排序,然后循环原始对象,通过比较另一个键插入排序后的索引。这就是我尝试过的:

var keys = Object.keys(data);
var result = {};
var numkeys;
for(var i=0; i < keys.length; i++) {
    if(!numkeys) {
        var numkeys = _.keys(_.pick(data[keys[i]][0], _.isNumber));
  }

        for(var j=0;j<numkeys.length;j++) {
    var sorted = _.sortBy(data['a'], numkeys[j]);
        _.forEach(sorted, function(n, k) {

        //THIS FAILS
        var t = _.set(_.where(data[keys[i]], {keyone: n.keyone}), keys[i]+'rank', k);
        console.log(t);
        });

    }
  }
var-keys=Object.keys(数据);
var result={};
var numkeys;
对于(变量i=0;i对于(var j=0;j仅在普通Javascript中:

对于排名,数据必须以某种方式进行排序

此解决方案的特点是一个数组,其中包含对象和对
data
中给定对象的引用。然后对所有项进行排序,原始数据获得它们的
rankgroup
rankall
属性

编辑:现在,重复项的排名相同

var data={a:[{keyone:'g',keytwo:'tina',keythree:21,keythree:15},{keyone:'anna',keythree:21,keythree:15},{keyone:'s',keythree:15},{keyone:'s',keythree anna',keythree keythree keythree:7,keythree:15},b:[{keyone:f',keytwo:any',keytwo:45,keyfour:100},{keyone:b',keytwo:any',keytwo:146,keyfour:100},{keyone:t',keytwo:any',keytwo:23,keyfour:100},
组={};
Object.keys(数据).reduce(函数(r,k){
返回r.concat(数据[k].map(函数(a)){
返回{obj:k,ref:a};
}));
},[])。排序(函数(a,b){
返回a.ref.keytree-b.ref.keytree | | a.ref.keytree-b.ref.keytree;
}).forEach(函数(a、i、aa){
if(i&&a.ref.keytree==aa[i-1].ref.keytree&&a.ref.keytree===aa[i-1].ref.keytree){
a、 ref.rankgroup=组[a.obj];
a、 ref.rankall=group.rankall;
}否则{
组[a.obj]=(组[a.obj]| | 0)+1;
group.rankall=(group.rankall | | 0)+1;
a、 ref.rankgroup=组[a.obj];
a、 ref.rankall=group.rankall;
}
});

document.write(''+JSON.stringify(data,0,4)+'');
我就是这样实现的

  • 将所有
    keytree
    收集到一个数组中并对它们进行排序(根据
    索引分配
    rankall

  • 排名

    _.forEach(a, function(n, k) {
        if (all.indexOf(n.keythree) !== -1) {
            dupes.push(n.keythree);
        }
        all.push(n.keythree);
    });
    
  • 检查这个


    编辑 我正在为复制品创建另一个阵列

        function getGlobalRank(n) {
        var val = n.keythree;
        if (sorted_dupes[val] === undefined) {
            sorted_dupes[val] = [];
            _.forEach(data, function(a, key) {
                _.forEach(_.where(a, {
                    keythree: val
                }), function(b) {
                    sorted_dupes[val].push(b);
                });
            });
            sorted_dupes[val] = _.sortByAll(sorted_dupes[val], ['keyfour', 'keytwo', 'keyone']);
        }
        return _.findIndex(sorted_dupes[val], {
            keyone: n.keyone,
            keytwo: n.keytwo,
            keythree: n.keythree,
            keyfour: n.keyfour
        }) + 1 + all.indexOf(val);
    }
    
    以及获得这些重复项目的全球排名

    查看项目是否基于以下顺序中的所有属性进行排序:
    keytree
    keyfour
    keytoo
    keyone
    (如果需要,可以在
    .sortByAll
    中更改顺序)

    代码看起来比我想象的更难看。将很快更新重构后的代码


    检查整个数据集中的as是什么意思?你是指
    a
    b
    还是
    a
    b
    ?应该对每个子数组进行排序,即a和be,并且应该对整个对象数组进行w.r.t.排序。我将更新我的描述以添加这一事实。请添加an排序数组的示例。我不想对其排序,排序会使我丢失原始索引。我想计算秩。我将发布一个包含秩的结果数组。非常感谢!小提琴看起来很完美!让我在实际数据中尝试一下!我如何检查重复项?我的意思是,对于重复值,排序将如何工作?我正在接受我可以理解并修改您的答案,以便以类似的方式对我的数据集中的所有
    数值
    值进行排序。仅将不重复的值推送到
    所有
    数组,结果为1)项目在其组中的排名正确,但2)多个项目可以在全球排名相同!我在查看代码时了解到了这一点。再次感谢。@Rutwick Gangurde您检查了更新的答案吗?有什么帮助吗?谢谢!我也在尝试这一个。Upvoting。我最终使用了@Venugopal的解决方案,因为我可以根据自己的目的修改它这涉及到对我的数据中的所有
    数值进行排序。你只需添加更多排序组即可
    返回a.ref.keytree-b.ref.keytree | a.ref.keyfour-b.ref.keyfour
    | a.ref.keyfive-b.ref.keyfive
    ,依此类推。让我试试。你如何处理同一对象中存在重复的情况?重复应该得到同样的排名。
    _.forEach(a, function(n, k) {
        if (all.indexOf(n.keythree) !== -1) {
            dupes.push(n.keythree);
        }
        all.push(n.keythree);
    });
    
        function getGlobalRank(n) {
        var val = n.keythree;
        if (sorted_dupes[val] === undefined) {
            sorted_dupes[val] = [];
            _.forEach(data, function(a, key) {
                _.forEach(_.where(a, {
                    keythree: val
                }), function(b) {
                    sorted_dupes[val].push(b);
                });
            });
            sorted_dupes[val] = _.sortByAll(sorted_dupes[val], ['keyfour', 'keytwo', 'keyone']);
        }
        return _.findIndex(sorted_dupes[val], {
            keyone: n.keyone,
            keytwo: n.keytwo,
            keythree: n.keythree,
            keyfour: n.keyfour
        }) + 1 + all.indexOf(val);
    }