0

I currently have a complex orders array (coming from a JSON client) that contains multiple orders like this (contains 2):

       0:  {
"employee": "Nicole"
"total": 13
"lineItems": {
    "elements": [2]
        0:  {
            "name": "Burger"
            "price": 8
        }
        1:  {
            "name": "Lamb"
            "price": 6.50
        }
    }
}
1:  {
"employee": "Dan"
"total": 11
"lineItems": {
"elements": [2]
        0:  {
            "name": "Lamb"
            "price": 4.50
        }
        1:  {
            "name": "Meatballs"
            "price": 6.50
        }
    }
}

What I want to do is create a new array that loops through the above and creates new items array based on the name of the lineItems object above. i.e. final output looks something like this:

var items = {
  "Burger" = {
    "totalSpent" : 8
  },
  "Lamb" = {
    "totalSpent" : 13
    // Note this totalSpent is an iteration or sum of all "price" items where name/id = "Lamb"
  },
  "Meatballs" = {
    "totalSpent" : 4.50
  }
}

I'm more used to PHP and have tried a number of different versions of this but can't seem to get the desired output. Here's what I've got so far:

    var orders = //As above//
    // Initialising new array to hold my final values
    var orderItems = [];
    for (var i = 0, len = orders.length; i < len; i++){
       for(var e = 0, leng = orders[i]['lineItems']['elements'].length; e < leng; e++){
          var totalSpent = 0;
          var id = orders[i]['lineItems']['elements'][e]['name'];
          if (orders[id] in orderItems[id]){
              // overwrite existing array item
              orderItems[id]['totalSpent'] += orders[i]['lineItems']['elements'][e]['price'];
              orderItems[id].push({totalSpent : orderItems[id]['totalSpent']}); 
          }
          else {
              // Create new array item
              orderItems.push(id);
              orderItems[id].push({totalSpent : orders[i]['lineItems']['elements'][e]['price']});
          }
       }
    }
contool
  • 1,034
  • 3
  • 18
  • 29
  • 2
    The Object is invalid. You have two `{` in the starting. Is it right? No commas, No `[]` for arrays, and nothing! – Praveen Kumar Purushothaman Feb 02 '16 at 18:13
  • and no commas at all – Gavriel Feb 02 '16 at 18:15
  • `orders` is not an array but object, so you should use [for .. in][1] instead of [for][2]. Also you `orders` is not valid js object cause of missing commas. Check this links [js_objects][3] and [Working_with_Objects][4]. [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in [2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for [3]: http://www.w3schools.com/js/js_objects.asp [4]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects – Viktor Kukurba Feb 02 '16 at 18:20
  • apologies - that initial array is coming in from a JSON interface, hence the lack of formatting. I've updated with a copy and paste of the actual data rather than a bad translation into JS. – contool Feb 02 '16 at 18:25
  • @contool Still, **wrong**! – Praveen Kumar Purushothaman Feb 02 '16 at 18:27

2 Answers2

1

Edit:

  • Had to correct your orders syntax, I added it to my answer so you can run the Javascript Snippet;
  • Changed the whole dot notation to bracket notation to make it easier to read and understand;
  • Corrected the bug about items remaining an empty array (it was in the inner for);

    var orders = [
        {
            "employee": "Nicole",
            "total": 13,
            "lineItems": {
                "elements": [
                    {
                        "name": "Burger",
                        "price": 8
                    },
                    {
                        "name": "Lamb",
                        "price": 6.50
                    }
                ]
            }
        },
        {
            "employee": "Dan",
            "total": 11,
            "lineItems": {
                "elements": [
                    {
                        "name": "Lamb",
                        "price": 4.50
                    },
                    {
                        "name": "Meatballs",
                        "price": 6.50
                    }
                ]
            }
        }
    ];

    var items = {};

    // loop in orders array
    for (var i = 0; i < orders.length; i++) {
        var elements = orders[i]["lineItems"]["elements"];

        // loop in orders[i]["lineItems"]["elements"] object
        for (var eIndex in orders[i]["lineItems"]["elements"]) {
            
            // Add new item if it doesn't already exist
            if (!items.hasOwnProperty(elements[eIndex]["name"])) {
                items[elements[eIndex]["name"]] = {"totalSpent": elements[eIndex]["price"]};

            } else {
                // If it exists, sum totalSpent
                items[elements[eIndex]["name"]]["totalSpent"] += elements[eIndex]["price"];
            }
        }
    }

    console.log(items);

PS: To find out why I'm using bracket notation instead of dot notation, check this question, it's good to know!

Community
  • 1
  • 1
Edson Horacio Junior
  • 3,033
  • 2
  • 29
  • 50
  • Thanks Edson - seems like it's going the right way. I tried plugging this in to what I have and console.log on the final items array - but the array is showing up empty. I have also recorded the loops though and it does seem to be looping correctly, not showing any errors, but doesn't seem to be assigning any values to the final array - any thoughts? – contool Feb 02 '16 at 19:10
  • 1
    Thanks @edson-horacio-junior - that's working perfectly - simple and easy to understand. Appreciate the input – contool Feb 03 '16 at 09:59
0

First of all, there are some error in your order array, note the difference between {} (for objects) and []. Then it is just simple use of the map function to iterate over the arrays.

See your browser console (F12) for the result of this snippet

var orders = [{
  "employee": "Nicole",
  "total": 13,
  "lineItems": {
    "elements": [{
      "name": "Burger",
      "price": 8
    }, {
      "name": "Lamb",
      "price": 6.50
    }
                ]
  }
}, {
  "employee": "Dan",
  "total": 11,
  "lineItems": {
    "elements": [{
      "name": "Lamb",
      "price": 6.50
    }, {
      "name": "Meatballs",
      "price": 4.50
    }]
  }
}]

var items = {}

orders.map(function(order) {
  order.lineItems.elements.map(function(elem) {
    if (items[elem.name]) {
      items[elem.name].totalSpent += elem.price
    } else {
      items[elem.name] = {"totalSpent": elem.price}
    }
  })
})

console.log(items)
Thijs D
  • 762
  • 5
  • 20
  • Thanks Thijs - the initial array is a JSON array, multidimensional. I must admit that I'm not familiar with a JS distinction between objects and keys. Each item is accessible in the array if you call it directly like orders[0]['employee'] etc. – contool Feb 02 '16 at 19:19