如何在JavaScript中基于数组中对象的属性对数组进行排序

时间:2022-03-04 15:58:59

I have array which holds a lot of objects in the following format:

我有一个数组,它以下列格式包含很多对象:

var data = [
  {
    vs: "23434",
    ip: "129.23.321.5"
  },
  {
    vs: "23454",
    ip: "129.23.321.6"
  },
  {
    vs: "23434",
    ip: "129.23.321.8"
  }
];

Now I want to sort them in a way where there is an array that holds objects in the following format:

现在我想以一种方式对它们进行排序,其中有一个数组以下列格式保存对象:

var dataFinal = [
  {
    vs: "23434",
    ip: ["129.23.321.5", "129.23.321.8"]
  }
  {
    vs: "98647",
    ip: ["129.23.321.6"]
  }
];

So basically, the data var will have multiple objects in it where there could be multiple ip with the same vs. I want to sort them in a way where an array will have multiple objects, one each for each vs, but the ip will be another array that will contain all the ip's for that vs.

所以基本上,数据var将有多个对象,其中可能有多个ip相同而我希望以一种方式对它们进行排序,其中一个数组将具有多个对象,每个对应一个,但是ip将是另一个包含所有ip的数组

What would be the best way to do this in javascript?

在javascript中执行此操作的最佳方法是什么?

2 个解决方案

#1


2  

I think this is a programming technique issue that is not related to a specific language.

我认为这是一个与特定语言无关的编程技术问题。

Javascript does not provide a "native" way to do such kind of task. The way you describe in you comment is totally fine. If you find yourself dealing with these kind of tasks very often, you could use some third party libraries like underscore to reduce bioplate codes.

Javascript不提供执行此类任务的“本机”方式。你在评论中描述的方式完全没问题。如果您发现自己经常处理这类任务,可以使用一些第三方库(如下划线)来减少bioplate代码。

The underscore way to solve this:

解决这个问题的下划线方式:

function mergeVsUseUnderscore(data) {
    var dataFinal = [],
    vsInFinal;

    _.each(data, function(item) {
        vsInFinal = _.find(dataFinal, function(itemFinal) {
            return itemFinal.vs === item.vs;
        });

        if(vsInFinal) {
            vsInFinal.ip.push(item.ip);
        } else {
            dataFinal.push({
                vs: item.vs,
                ip: [item.ip]
            })
       }
    });

    return dataFinal;
}

One more thing to mention, simply use _.groupBy(data, 'vs') will produce:

还有一件事要提,只需使用_.groupBy(data,'vs')就会产生:

{ 
    '23434': [ 
        { vs: '23434', ip: '129.23.321.5' },
        { vs: '23434', ip: '129.23.321.8' } 
    ],
    '23454': [ { vs: '23454', ip: '129.23.321.6' } ] 
}

#2


1  

var data = [{
    vs: "1",
    ip: "129.23.321.6"
}, {
    vs: "2",
    ip: "129.23.321.8"
}, {
    vs: "0",
    ip: "129.23.321.5"
}, ];

var transformed = data.reduce(function (memo, datum) {

    var filterFunc = function (_datum) {

        return datum.vs === _datum.vs;

    };

    if (!memo.some(filterFunc)) {

        memo.push({
            vs: datum.vs,
            ip: [datum.ip]
        });

    } else {

        memo.filter(filterFunc)[0].ip.push(datum.ip)

    }

    return memo;

}, []);

var sorted = transformed.sort(function (a, b) {

    if (a.vs > b.vs) {

        return 1;

    } else if (a.vs < b.vs) {

        return -1;

    } else {

        return 0;

    }

});

console.log(JSON.stringify(sorted));

Fiddle

小提琴

#1


2  

I think this is a programming technique issue that is not related to a specific language.

我认为这是一个与特定语言无关的编程技术问题。

Javascript does not provide a "native" way to do such kind of task. The way you describe in you comment is totally fine. If you find yourself dealing with these kind of tasks very often, you could use some third party libraries like underscore to reduce bioplate codes.

Javascript不提供执行此类任务的“本机”方式。你在评论中描述的方式完全没问题。如果您发现自己经常处理这类任务,可以使用一些第三方库(如下划线)来减少bioplate代码。

The underscore way to solve this:

解决这个问题的下划线方式:

function mergeVsUseUnderscore(data) {
    var dataFinal = [],
    vsInFinal;

    _.each(data, function(item) {
        vsInFinal = _.find(dataFinal, function(itemFinal) {
            return itemFinal.vs === item.vs;
        });

        if(vsInFinal) {
            vsInFinal.ip.push(item.ip);
        } else {
            dataFinal.push({
                vs: item.vs,
                ip: [item.ip]
            })
       }
    });

    return dataFinal;
}

One more thing to mention, simply use _.groupBy(data, 'vs') will produce:

还有一件事要提,只需使用_.groupBy(data,'vs')就会产生:

{ 
    '23434': [ 
        { vs: '23434', ip: '129.23.321.5' },
        { vs: '23434', ip: '129.23.321.8' } 
    ],
    '23454': [ { vs: '23454', ip: '129.23.321.6' } ] 
}

#2


1  

var data = [{
    vs: "1",
    ip: "129.23.321.6"
}, {
    vs: "2",
    ip: "129.23.321.8"
}, {
    vs: "0",
    ip: "129.23.321.5"
}, ];

var transformed = data.reduce(function (memo, datum) {

    var filterFunc = function (_datum) {

        return datum.vs === _datum.vs;

    };

    if (!memo.some(filterFunc)) {

        memo.push({
            vs: datum.vs,
            ip: [datum.ip]
        });

    } else {

        memo.filter(filterFunc)[0].ip.push(datum.ip)

    }

    return memo;

}, []);

var sorted = transformed.sort(function (a, b) {

    if (a.vs > b.vs) {

        return 1;

    } else if (a.vs < b.vs) {

        return -1;

    } else {

        return 0;

    }

});

console.log(JSON.stringify(sorted));

Fiddle

小提琴