如何使用id javascript对group对象求和并得到最大值

时间:2016-09-20 05:24:06

标签: javascript

var myArray = [
  {"Emiten_ID":'SMBR',"Lot":500,"Price":2500},     
  {"Emiten_ID":'SMBR',"Lot":300,"Price":2200},     
  {"Emiten_ID":'ELSA',"Lot":500,"Price":1000},
  {"Emiten_ID":'SMBR',"Lot":100,"Price":3000},     
  {"Emiten_ID":'BI',"Lot":300,"Price":500},     
  {"Emiten_ID":'AAI',"Lot":200,"Price":1300},
  {"Emiten_ID":'BTB',"Lot":700,"Price":2900},     
  {"Emiten_ID":'BI',"Lot":150,"Price":200},     
  {"Emiten_ID":'AAI',"Lot":200,"Price":600},
];

我想要这样的结果,我从批次中得到总和从价格中得到最大值

var Result= [
  {"Emiten_ID":'ELSA',"Lot":500,"Price":1000},
  {"Emiten_ID":'SMBR',"Lot":900,"Price":3000},     
  {"Emiten_ID":'BI',"Lot":450,"Price":500},     
  {"Emiten_ID":'BTB',"Lot":700,"Price":2900},     
  {"Emiten_ID":'AAI',"Lot":400,"Price":1300},
];

8 个答案:

答案 0 :(得分:2)

您可以将Array#forEach和一个对象用作哈希表,并按Emiten_ID对其进行分组。

var myArray = [{ "Emiten_ID": 'SMBR', "Lot": 500, "Price": 2500 }, { "Emiten_ID": 'SMBR', "Lot": 300, "Price": 2200 }, { "Emiten_ID": 'ELSA', "Lot": 500, "Price": 1000 }, { "Emiten_ID": 'SMBR', "Lot": 100, "Price": 3000 }, { "Emiten_ID": 'BI', "Lot": 300, "Price": 500 }, { "Emiten_ID": 'AAI', "Lot": 200, "Price": 1300 }, { "Emiten_ID": 'BTB', "Lot": 700, "Price": 2900 }, { "Emiten_ID": 'BI', "Lot": 150, "Price": 200 }, { "Emiten_ID": 'AAI', "Lot": 200, "Price": 600 }, ],
    result = [];

myArray.forEach(function (a) {
    if (!this[a.Emiten_ID]) {
        this[a.Emiten_ID] = { Emiten_ID: a.Emiten_ID, Lot: 0, Price: 0 };
        result.push(this[a.Emiten_ID]);
    }
    this[a.Emiten_ID].Lot += a.Lot;
    this[a.Emiten_ID].Price = Math.max(this[a.Emiten_ID].Price, a.Price);
}, Object.create(null));

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

ES6,关闭hash而不使用this

var myArray = [{ "Emiten_ID": 'SMBR', "Lot": 500, "Price": 2500 }, { "Emiten_ID": 'SMBR', "Lot": 300, "Price": 2200 }, { "Emiten_ID": 'ELSA', "Lot": 500, "Price": 1000 }, { "Emiten_ID": 'SMBR', "Lot": 100, "Price": 3000 }, { "Emiten_ID": 'BI', "Lot": 300, "Price": 500 }, { "Emiten_ID": 'AAI', "Lot": 200, "Price": 1300 }, { "Emiten_ID": 'BTB', "Lot": 700, "Price": 2900 }, { "Emiten_ID": 'BI', "Lot": 150, "Price": 200 }, { "Emiten_ID": 'AAI', "Lot": 200, "Price": 600 }, ],
    result = [];

myArray.forEach((hash => a => {
    if (!hash[a.Emiten_ID]) {
        hash[a.Emiten_ID] = { Emiten_ID: a.Emiten_ID, Lot: 0, Price: 0 };
        result.push(hash[a.Emiten_ID]);
    }
    hash[a.Emiten_ID].Lot += a.Lot;
    hash[a.Emiten_ID].Price = Math.max(hash[a.Emiten_ID].Price, a.Price);
})(Object.create(null)));

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

答案 1 :(得分:2)

您可以使用linq.js库:



var myArray = [
  {"Emiten_ID":'SMBR',"Lot":500,"Price":2500},     
  {"Emiten_ID":'SMBR',"Lot":300,"Price":2200},     
  {"Emiten_ID":'ELSA',"Lot":500,"Price":1000},
  {"Emiten_ID":'SMBR',"Lot":100,"Price":3000},     
  {"Emiten_ID":'BI',"Lot":300,"Price":500},     
  {"Emiten_ID":'AAI',"Lot":200,"Price":1300},
  {"Emiten_ID":'BTB',"Lot":700,"Price":2900},     
  {"Emiten_ID":'BI',"Lot":150,"Price":200},     
  {"Emiten_ID":'AAI',"Lot":200,"Price":600},
];
var answer = Enumerable.From(myArray).GroupBy("x => x.Emiten_ID", "x => {Lot: x.Lot, Price: x.Price}").Select("x => {Emiten_ID:x.Key(), Lot:x.Sum(y=>y.Lot), Price:x.Max(y=>y.Price)}").ToArray();
answer.forEach(x => console.log(x));

<script data-require="jquery@3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script data-require="linq.js@2.2.0+2" data-semver="2.2.0+2" src="//cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>
<script data-require="linq.js@2.2.0+2" data-semver="2.2.0+2" src="//cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/jquery.linq.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:2)

使用ECMAScript 2015(或polyfill)中提供的Map类:

var temp = new Map();

for (var item of myArray) {
    var e = temp.get(item.Emiten_ID)
    if (e) {
        e.Lot += item.Lot;
        e.Price = Math.max( e.Price, item.Price );
    } else {
        temp.set( item.Emiten_ID, 
            { Emiten_ID: item.Emiten_ID, Lot:item.Lot, Price:item.Price })
    }
}

var result = Array.from(temp.values());

console.log(result)

答案 3 :(得分:1)

这是很好的方式, 希望有更简单的方法。

var myArray = [
  {"Emiten_ID":'SMBR',"Lot":500,"Price":2500},     
  {"Emiten_ID":'SMBR',"Lot":300,"Price":2200},     
  {"Emiten_ID":'ELSA',"Lot":500,"Price":1000},
  {"Emiten_ID":'SMBR',"Lot":100,"Price":3000},     
  {"Emiten_ID":'BI',"Lot":300,"Price":500},     
  {"Emiten_ID":'AAI',"Lot":200,"Price":1300},
  {"Emiten_ID":'BTB',"Lot":700,"Price":2900},     
  {"Emiten_ID":'BI',"Lot":150,"Price":200},     
  {"Emiten_ID":'AAI',"Lot":200,"Price":600},
];

var sortedIds = [];
var Result = [];
function sortArray(){

    for(var i = 0; i < myArray.length; i++){
        if(myArray.indexOf(myArray[i].Emiten_ID) < 0){
            sortedIds.push(myArray[i].Emiten_ID);
            Result.push({
                "Emiten_ID" : myArray[i].Emiten_ID,
                "Lot"       : sumLot(myArray[i].Emiten_ID),
                "Price"     : maxPrice(myArray[i].Emiten_ID);
            });


        }
    }   

    //out put
    console.log(Result);
}

function sumLot(id){
    var sum = 0;
    for(var i = 0; i < myArray.length; i++){
        if(myArray[i].Emiten_ID == id){
            sum += myArray[i].lot;
        }
    }   
    return sum;
}

function maxPrice(id){
    var max = 0;
    for(var i = 0; i < myArray.length; i++){
        if(myArray[i].Price > max){
            max = myArray[i].Price;
        }
    }   
    return max;
}

答案 4 :(得分:1)

&#13;
&#13;
var myArray = [
  {"Emiten_ID":'SMBR',"Lot":500,"Price":2500},     
  {"Emiten_ID":'SMBR',"Lot":300,"Price":2200},     
  {"Emiten_ID":'ELSA',"Lot":500,"Price":1000},
  {"Emiten_ID":'SMBR',"Lot":100,"Price":3000},     
  {"Emiten_ID":'BI',"Lot":300,"Price":500},     
  {"Emiten_ID":'AAI',"Lot":200,"Price":1300},
  {"Emiten_ID":'BTB',"Lot":700,"Price":2900},     
  {"Emiten_ID":'BI',"Lot":150,"Price":200},     
  {"Emiten_ID":'AAI',"Lot":200,"Price":600},
];

myArray = myArray.sort(function(a,b){
	if(a.Emiten_ID > b.Emiten_ID)
		return 1;
	else if(a.Emiten_ID < b.Emiten_ID)
		return -1;
	else{
		return a.Price - b.Price;
	}
});

var result = [myArray[0]];

for(var i = 1 ; i < myArray.length ; i ++){
	var obj = myArray[i];
	var res = result[result.length - 1];
	
	if(obj.Emiten_ID == res.Emiten_ID){
		res.Lot += obj.Lot;
		res.Price = Math.max(res.Price,obj.Price);
	}else{
		result.push(obj);
	}

}

console.log(result);
&#13;
&#13;
&#13;

答案 5 :(得分:1)

使用lodash的解决方案:

_.chain(myArray).groupBy('Emiten_ID').map(emiten => ({
  "Emiten_ID":emiten[0]['Emiten_ID'],
  "Lot": _.sumBy(emiten, 'Lot'),
  "Price": _.maxBy(emiten, 'Price')['Price']
})).value()

答案 6 :(得分:1)

  • 迭代所有array元素
  • 从新数组
  • 中查找each-element的索引
  • 如果元素不存在,请将其推送到array
  • 如果元素存在,请将Lot的值相加,如果Price的值更高,则覆盖更高的值

var myArray = [{
        "Emiten_ID": 'SMBR',
        "Lot": 500,
        "Price": 2500
    }, {
        "Emiten_ID": 'SMBR',
        "Lot": 300,
        "Price": 2200
    }, {
        "Emiten_ID": 'ELSA',
        "Lot": 500,
        "Price": 1000
    }, {
        "Emiten_ID": 'SMBR',
        "Lot": 100,
        "Price": 3000
    }, {
        "Emiten_ID": 'BI',
        "Lot": 300,
        "Price": 500
    }, {
        "Emiten_ID": 'AAI',
        "Lot": 200,
        "Price": 1300
    }, {
        "Emiten_ID": 'BTB',
        "Lot": 700,
        "Price": 2900
    }, {
        "Emiten_ID": 'BI',
        "Lot": 150,
        "Price": 200
    }, {
        "Emiten_ID": 'AAI',
        "Lot": 200,
        "Price": 600
    }];
    var newArr = [];

    myArray.forEach(function (el) {
        var findIndex = newArr.findIndex(function (item) {
            return item.Emiten_ID === el.Emiten_ID;
        });
        if (findIndex === -1) {
            newArr.push(el);
        } else if (el.Price > newArr[findIndex].Price) {
            newArr[findIndex].Price = el.Price;
            newArr[findIndex].Lot += el.Lot;
        } else {
            newArr[findIndex].Lot += el.Lot;
        }
    });
    console.log(JSON.stringify(newArr, null, 4));

答案 7 :(得分:1)

让我们尝试分解这个。我们首先编写一个通用实用程序函数,我们将调用它combine,它使用为名为combiners的哈希中的每个属性指定的函数组合对象的属性:

function combine(array, combiners) {
  const result = {};
  for (prop of Object.keys(combiners)) {
    result[prop] = combiners[prop](...array.map(elt => elt[prop]));
  }
  return result;
}

使用此示例:

combine(
  [{a: 1, b: 10}, {a: 42, b: 80}],
  {a: sum, b: Math.max}
)

将导致

{a: 43, b: 80}

当然,为了完成这项工作,我们必须定义sum

function sum(...vals) { return vals.reduce(add); }

其中add只是

function add(a, b) { return a + b; }

接下来,我们将按Emiten_ID属性对输入进行分组。您可以使用Underscore的_.groupBy,或者自己编写(见下文)。

const groups = _.groupBy(myArray, 'Emiten_ID`);

这会产生类似

的内容
{ SMBR: [
    { Emiten_ID: 'SMBR', "Lot": 500, "Price": 2500},     
    { Emiten_ID: 'SMBR', "Lot": 300, "Price": 2200}
  ],
  ELSA: [
  ]
}

完成此准备工作后,只需使用我们的groups实用程序映射combine中的每个值,即可轻松获得结果:

const Result = Object.keys(groups).map(key =>
  combine(
    groups[key], 
    {
      Emiten_ID: identity, 
      Lot: sum, 
      Price: Math.max}));

其中identity只是

function identity(id) { return id; }

如果您希望抽象出映射对象属性combine中的概念,您可以再次使用Underscore中的一些实用程序,或者自己编写:

function mapObject(obj, fn) {
  const result = {};

  for (prop of obj) result[prop] = fn(obj[prop], prop);
  return result;
}

使用此示例:

mapObject({a: 2, b: 3}, x => x * x)
// yields {a: 4, b: 9}

现在你可以更简单地写一下combine,作为

function combine(array, combiners) {
  return mapObject(combiners, function(combiner, prop) {
    return combiner(...array.map(elt => elt[prop]));
  };
}

如果您不想使用下划线的_.groupBy,这里有一个本土版本:

function groupBy(array, prop) {
  var result = {};
  array.forEach(elt => (result[elt[prop]] = result[elt[prop]] || []).push(elt));
  return result;
}