MathewG MathewG - 2 months ago 11
Javascript Question

JS Combine an Object based on the same criteria

Hello fellow coders & kindred spirits,

each time a user clicks on a basket to add a product an object is created that is named:
field_x
where x is always + 1 starting from 1.

My goal is to create a function that checks if there is the same item already present multiple times and if yes then it should
take all the piece values, combine them together, substitute the piece value of the first item with this new number and delete all the
other matching arrays.

Here is a stringified example of what I have in mind:

Input:


  • field_1
    [{"name":"A","piece":1,"active":"true"}]

  • field_2
    [{"name":"B","piece":1,"active":"true"}]

  • field_3
    [{"name":"A","piece":1,"active":"true"}]

  • field_4
    [{"name":"C","piece":1,"active":"true"}]

  • field_5
    [{"name":"A","piece":1,"active":"true"}]

  • field_6
    [{"name":"A","piece":1,"active":"true"}]

  • field_7
    [{"name":"B","piece":1,"active":"true"}]

  • field_8
    [{"name":"C","piece":1,"active":"true"}]

  • field_9
    [{"name":"A","piece":1,"active":"true"}]

  • field_10
    [{"name":"A","piece":1,"active":"true"}]



Output:


  • field_1
    [{"name":"A","piece":6,"active":"true"}]

  • field_2
    [{"name":"B","piece":2,"active":"true"}]

  • field_3
    [{"name":"C","piece":2,"active":"true"}]



I should note that eval is not planned to be used in the final version.
I know it is not a good idea to use it and I know how to substitute it.

The code I have so far does not provide me with a solution and I do not know what to do next.

<script src="js/underscore.js"></script>

<script>
var fieldsNumber = 10;

var field_1 = new Array();
var field_2 = new Array();

var field_3 = new Array();
var field_4 = new Array();

var field_5 = new Array();
var field_6 = new Array();

var field_7 = new Array();
var field_8 = new Array();

var field_9 = new Array();
var field_10 = new Array();

var tempField01 = new Array();
var tempField02 = new Array();

var tempField03 = new Array();
var tempField04 = new Array();

field_1.push({
name: 'A',
piece: 1,
active: 'true'
});
field_2.push({
name: 'B',
piece: 1,
active: 'true'
});

field_3.push({
name: 'A',
piece: 1,
active: 'true'
});
field_4.push({
name: 'C',
piece: 1,
active: 'true'
});

field_5.push({
name: 'A',
piece: 1,
active: 'true'
});
field_6.push({
name: 'A',
piece: 1,
active: 'true'
});

field_7.push({
name: 'A',
piece: 1,
active: 'true'
});
field_8.push({
name: 'A',
piece: 1,
active: 'true'
});

field_9.push({
name: 'A',
piece: 1,
active: 'true'
});
field_10.push({
name: 'A',
piece: 1,
active: 'true'
});


var jSorageItemContents = new Array();

//HEADER START
for (var i = 1; i < fieldsNumber + 1; i++) {

console.log("======================");
console.log("field_" + i);
console.log(JSON.stringify(eval("field_" + i)));

} //HEADER END



console.log("======================");
console.log("----------------------");

for (var i = 1; i < fieldsNumber + 1; i++) {

console.log(i);


for (var n = 1; n < fieldsNumber + 1; n++) {

var tempField01 = eval("field_" + i);
var tempField02 = eval("field_" + n);


var docA = _.omit(tempField01, ['price']);
var docB = _.omit(tempField02, ['price']);

// console.log("-----------------");
// console.log('docA');
// console.log(JSON.stringify(docA));
//
// console.log('tempField02');
// console.log(JSON.stringify(docB));
//
// console.log("-----------------");


if (docA[0].done == 'true' || docB[0].done == 'true') {

} else {



if (Object.is(JSON.stringify(docA), JSON.stringify(docB))) {


// console.log("field_" + i + " and field_" + n + " do match!");
// console.log('Lets Rock and Roll');




// console.log("field_" + i + "[0].piece");
// console.log(eval("field_" + i + "[0]['piece']"));
var kusA = parseInt(eval("field_" + i + "[0]['piece']"), 10);
var kusB = parseInt(eval("field_" + n + "[0]['piece']"), 10);

var noveKusy = kusA + kusB;
var nula = 0;

eval("field_" + i + "[0]['piece'] = " + noveKusy);

eval("field_" + i + "[0]['done'] = true");
eval("field_" + n + "[0]['done'] = true");
eval("field_" + n + "[0]['active'] = false");



} else {

// console.log("field_" + i + " sa s field_" + n + " do not match");

}
}
}
// }
}

console.log("======================");
console.log("======================");
console.log("======================");


//FOOTER START
for (var i = 1; i < fieldsNumber + 1; i++) {

console.log("======================");
console.log("field_" + i);
console.log(JSON.stringify(eval("field_" + i)));

} //FOOTER END




Any suggestion is appreciated!

Answer

I suggest to use a better structure for the collecting parts in an array. Then you can iterate over the array with Array#forEach and group the parts.

var data = [{ name: "A", piece: 1, active: "true" }, { name: "B", piece: 1, active: "true" }, { name: "A", piece: 1, active: "true" }, { name: "C", piece: 1, active: "true" }, { name: "A", piece: 1, active: "true" }, { name: "A", piece: 1, active: "true" }, { name: "B", piece: 1, active: "true" }, { name: "C", piece: 1, active: "true" }, { name: "A", piece: 1, active: "true" }, { name: "A", piece: 1, active: "true" }],
    grouped = [];

data.forEach(function (a) {
    if (!this[a.name]) {
        this[a.name] = { name: a.name, piece: 0, active: a.active };
        grouped.push(this[a.name]);
    }
    this[a.name].piece += a.piece;
}, Object.create(null));

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

For an even better structure, i suggest to use an object, with name as key and get an easy access to the count and other data of the item, like

var items = {
    A: {
        name: "A",
        piece: 1,
        active: "true"
    },
    B: {
        name: "B",
        piece: 1,
        active: "true"
    },
    C: {
        name: "C",
        piece: 1,
        active: "true"
    }
};

Edit, key with multiple parameters

var dataToProcess = [{ "row": 4, "col": 3, "kg_m": "1.36", "m_t": "735", "v_d": 5000, "selectedTransection": "rectangle", "dCellText": "30x20", "mmCellText": "2", "active": "true", "piece": 1 }, { "row": 4, "col": 3, "kg_m": "1.36", "m_t": "735", "v_d": 6000, "selectedTransection": "rectangle", "dCellText": "30x20", "mmCellText": "2", "active": "true", "piece": 1 }, { "row": 4, "col": 3, "kg_m": "1.92", "m_t": "521", "v_d": 5000, "selectedTransection": "circle", "dCellText": "33.7", "mmCellText": "2.5", "active": "true", "piece": 1 }, { "row": 5, "col": 1, "kg_m": "1.78", "m_t": "562", "v_d": 6000, "selectedTransection": "circle", "dCellText": "38", "mmCellText": "2", "active": "true", "piece": 20 }, { "row": 5, "col": 1, "kg_m": "1.78", "m_t": "562", "v_d": 6000, "selectedTransection": "circle", "dCellText": "38", "mmCellText": "2", "active": "true", "piece": 1 }],
    dataProcessed = [];

dataToProcess.forEach(function (a) {
    var key = [a.name, a.col, a.kg_m, a.m_t, a.v_d, a.selectedTransection, a.dCellText, a.mmCellText].join('|');
    if (!this[key]) {
        this[key] = {
            row: a.row,
            col: a.col,
            kg_m: a.kg_m,
            m_t: a.m_t,
            v_d: a.v_d,
            selectedTransection: a.selectedTransection,
            dCellText: a.dCellText,
            mmCellText: a.mmCellText,
            active: a.active,
            piece: 0
        };
        dataProcessed.push(this[key]);
    }
    this[key].piece += a.piece;
}, Object.create(null));

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