3

I have an array (json) of products (around 5000) where each product is represented in two arrays as shown below;

["PC01","Product 1","11"],
["PC01","Product 1","17"]

The only difference is, the 11 and 17 strings both representing the first and second price of the product.

I am trying to find a way to merge this array into a single one so that each product is represented as one such as: ["PC01", "Product 1", "11", "17"]

I have tried looping and forming an object of products which I found not quite safe due to various reasons and one of them being the order of the prices are unknown. So at first I might get the highest price first and lowest price second while on the other hand, another array would have the lowest one first and highest the second.. This is my current code;

var products = [];
$.getJSON('data.json', function (data) {
    $.each(data, function (key, val) {
        if (!key == 0) {
               // because I use the previous arrays info, 
               // only start if we HAVE a previous array hence;
            if (data[key][0] != data[key - 1][0]) {
                var o = {}
                o.ProductCode = val[0];
                o.ProductName = val[1];
                o.Price1 = val[3];
                o.Price2 = data[key - 1][3];
                products.push(o);
            }
        }
    });
});

As I said, this relies on the fact that each product exists as two arrays and assumes the second price is the highest.

So, I am basically trying to find the most optimal way to parse the json to merge all double arrays and would be grateful if you could give me some ideas..

EDIT: Sample Data:

Note: Sample data have more information than I initially wrote in my question such as stock quantity, VAT rate etc. but omitted by me to prevent any confusions.

[
    [
        "AD.0001 ",
        "AD ALOE VERA MOUTHWASH w�th FLUORIDE 250ML ",
        " 691",
        " 11.51",
        " 16",
        " 96"
    ],
    [
        "AD.0001 ",
        "AD ALOE VERA MOUTHWASH w�th FLUORIDE 250ML ",
        " 691",
        " 17",
        " 16",
        " 96"
    ],
    [
        "AD.0002 ",
        "AD ALOE VERA MOUTHWASH 250ML ",
        " 692",
        " 11.51",
        " 16",
        " 75"
    ],
    [
        "AD.0002 ",
        "AD ALOE VERA MOUTHWASH 250ML ",
        " 692",
        " 17",
        " 16",
        " 75"
    ]
]
Vivek Jain
  • 3,811
  • 6
  • 30
  • 47
Subliminal Hash
  • 13,614
  • 20
  • 73
  • 104

4 Answers4

0

If the 1 and 2 always follow each other just do this:

var products = [
    ["A", 1], ["A", 2],
    ["B", 5], ["B", 2],
    ["C", 1], ["C", 2]
];

document.getElementById('input').innerHTML = JSON.stringify(products);    
var i = 0;
while(i < products.length) {
    var first = i,
    second = i + 1;

    if ( products[first][1] > products[second][1] ) {
        first = i + 1; second = i; // just switch the index..
    }

    products[first].push(products[second][1]);
    products.splice(second, 1);
    i++;
}

document.getElementById('result').innerHTML = JSON.stringify(products);
input
<pre id="input"></pre>
<br>
result
<pre id="result"></pre>
Vivek Jain
  • 3,811
  • 6
  • 30
  • 47
webdeb
  • 12,993
  • 5
  • 28
  • 44
  • Thank you webdeb, yes they always follow each other but there is no guarantee that the highest price will always be the second and I need the highest price to always be after the lowest one.. So, the json could read ["A",2],["A",1] So, I also need to sort this so that the lower price is always before the highest. – Subliminal Hash Nov 25 '15 at 07:26
  • Then you need to check which is higher.. I'll update my answer with respect to this info – webdeb Nov 25 '15 at 07:28
  • @Emin now it should work, see B which is first 5 and then 2, but the result is 2,5 – webdeb Nov 25 '15 at 07:38
  • Thanks webdeb your answer also works. I have just accepted the first answer that worked. – Subliminal Hash Nov 25 '15 at 07:58
  • I mention in the comments to the question that performance is no issue for me since this is only done one time everyday and auto-uploaded to the local server from the local machine. However, I do agree with you that typcially scenarios like this is usually live on the web and hence performance considerations and pre-cautions should be taken. This question and both answers therefore represents a valuable resource for those who might come accross here in the future with different scenarios.. – Subliminal Hash Nov 25 '15 at 08:17
0

Try something like this:

var productsbycode = {};
var products = [];
$.getJSON('data.json', function (data) {
    $.each(data, function (key, val) {
        if(typeof productsbycode[val[0]] !== "object"){
            productsbycode[val[0]] = {name: val[1], prices: [val[2]]};      
        } else{
            productsbycode[val[0]].prices.push(val[2]);
        }
    });
    $.each(productsbycode, function(key, val){
        var price1 = val['prices'][0];
        var price2 = val['prices'][1];
        if(price1 < price2){
            products.push([key, val['name'], price1, price2]);
        } else{
            products.push([key, val['name'], price2, price1]);
        }
    });
});

JSFiddle.

It works in any order and it does what you asked.

Update: The prices will now show the lowest first and then the highest.

Jacques Marais
  • 2,666
  • 14
  • 33
0

There is Linq for JavaScript (linq.js), a free JavaScript library available at CodePlex:

https://linqjs.codeplex.com/

Like C# LINQ it has a .distinct method which can help you to remove duplicates, amongst most LINQ query methods you know from C# made available in JavaScript.

Example:

var list = [
   { one: 2, two: 4, three: 1 },
   { one: 4, two: 7, three: 5 },
   { one: 2, two: 4, three: 1 },
   { one: 7, two: 3, three: 2 },
   ];
Enumerable.From(list).Distinct("$.one")
.OrderBy("$.a").ThenBy("$.two").ThenBy("$.three")
.Select("$.one + ':' + $.two + ':' + $.three")

Gives you the result:

2:4:1
4:7:5
7:3:2


More about LINQ.js: see this answer at SO

Community
  • 1
  • 1
Matt
  • 25,467
  • 18
  • 120
  • 187
0

More broadly, there's a cool library called Immutable.js which lets you manipulate complex JSON objects in a very clean way.

It provides methods to merge arrays and other arbitrary JSON objects and define your conflict resolution strategy.

Mayas
  • 1,434
  • 5
  • 16
  • 25
  • Thanks @Mayas however just so that it does not sound advertorial, can you please provide an example where you have applied the usage of the said library for this particular case for the future comers to this post to see? – Subliminal Hash Nov 25 '15 at 13:42