1

My current code pushes the key into normal array but i want to push both key and value in to array of object. I appreciate if an expert show me how this can be done.Thanks

Javascript to create the object array:

var xml ='<?xml version="1.0" encoding="UTF-8"?> <dict><key>ItemLists</key> <array><dict><key>id</key> <string>1</string> <key>name</key> <string>fruits</string> <key>category</key> <string>US Fruits</string> <key>categoryIcon</key> <string>http://www.somsite.com/categories/1.jpg</string> <key>country</key> <string>US</string> </dict> <dict><key>id</key> <string>2</string> <key>name</key> <string>Vegetable</string> <key>category</key> <string>Eu Vegetable</string> <key>categoryIcon</key> <string>http://www.somsite.com/categories/2.jpg</string> <key>country</key> <string>EU</string> </dict> </array> </dict>';

        xmlDoc = $.parseXML(xml),
        $xml = $(xmlDoc);

var MyArray=[];
$(xml).find("array key").each(function(){
    var key = $(this).text();
    var value = $(this).next().text();  
    console.log(key + "=" + value);
    //here  i want to create array of objects instead of normal array
    //and push both key and value to array of object
    MyArray.push(key);
});

Object array sample that i want construct:

var myArray = [{
    id: 1,
    name: 'fruits',
    category: 'US Fruits',
    categoryIcon: 'http://www.somsite.com/categories/1.jpg',
    country: 'US'
}, {
    id: 2,
    name: 'Vegetable',
    category: 'Eu Vegetable',
    categoryIcon: 'http://www.somsite.com/categories/2.jpg',
    country: 'EU'
}, ];

edit: I tried to print the array of objects like this but i got undefined for all values!:

$.each(MyArray,function(j, object){

var div = "<tr id=\""+j+"\">\n" +
    "<td>"+j+"</td>\n" +
    "<td><img src=\""+ object.categoryIcon +"\" height=\"42\" width=\"42\"></td>\n" +
    "<td>\n" +
    "<a href=\"javascript:doit('id=" + object.id + "&name=" + object.name + "&category=" + object.category + "&categoryIcon=" + object.categoryIcon + "','"+ object.country +"')\" onclick=\"selectLink(this);\">" + object.name + "</a><br> \n" +
    "<br></td></tr>\n\n";
 $("#myDiv").append(div);

});

2 Answers 2

5

If you just replace

MyArray.push(key);

with

var o = {};
o[key] = value;

MyArray.push(o);

It would do that, but you seem to want to iterate over each dict, and then get the value of each key inside the parent dict etc.

var xml = '<?xml version="1.0" encoding="UTF-8"?> <dict><key>ItemLists</key> <array><dict><key>id</key> <string>1</string> <key>name</key> <string>fruits</string> <key>category</key> <string>US Fruits</string> <key>categoryIcon</key> <string>http://www.somsite.com/categories/1.jpg</string> <key>country</key> <string>US</string> </dict> <dict><key>id</key> <string>2</string> <key>name</key> <string>Vegetable</string> <key>category</key> <string>Eu Vegetable</string> <key>categoryIcon</key> <string>http://www.somsite.com/categories/2.jpg</string> <key>country</key> <string>EU</string> </dict> </array> </dict>';

var xmlDoc = $.parseXML(xml),
    $xml = $(xmlDoc);

var MyArray = [];
$(xml).find("array dict").each(function(_,elem) {
	var o = {};
	$('key', elem).each(function() {
        var key = $(this).text();
        var value = $(this).next().text();
        o[key] = value;
    });
    MyArray.push(o);
});
console.log(MyArray)
.as-console-wrapper {top:0; min-height:100%!important}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Alternativetely, you could use map() and reduce()

var MyArray = $(xml).find("array dict").map(function(_,elem) {
    return $('key', elem).toArray().reduce(function(a,b) {
        return a[$(b).text()] = $(b).next().text(), a;
    }, {});
}).get();
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for replies. @adeneo i tried to use your first suggestion but now when i try to print the array of object i get all undefined for variables!(see my first post edit part). It seems the array didn't push the data correctly! could you tell me how to fix it ?
1

As you are collecting different objects, you should in fact have two loops: one for collecting the object properties for one dict, and one for collecting those objects into an array:

var myArray=[];
$(xml).find("array dict").each(function(){
    var obj = {};
    $(this).find("key").each(function () {
        var key = $(this).text();
        var value = $(this).next().text();  
        console.log(key + "=" + value);
        obj[key] = value;
    });
    myArray.push(obj);
});

With ES6 you can shorten this to the following code:

var myArray = $(xmlDoc).find("array dict").get().map( dict =>
    $(dict).find("key").get().reduce( (obj, el) =>
        Object.assign(obj, { [$(el).text()]: $(el).next().text() }), {}));

var xml ='<?xml version="1.0" encoding="UTF-8"?> <dict><key>ItemLists</key> <array><dict><key>id</key> <string>1</string> <key>name</key> <string>fruits</string> <key>category</key> <string>US Fruits</string> <key>categoryIcon</key> <string>http://www.somsite.com/categories/1.jpg</string> <key>country</key> <string>US</string> </dict> <dict><key>id</key> <string>2</string> <key>name</key> <string>Vegetable</string> <key>category</key> <string>Eu Vegetable</string> <key>categoryIcon</key> <string>http://www.somsite.com/categories/2.jpg</string> <key>country</key> <string>EU</string> </dict> </array> </dict>';

var xmlDoc = $.parseXML(xml);

var myArray = $(xmlDoc).find("array dict").get().map( dict =>
    $(dict).find("key").get().reduce( (obj, el) =>
        Object.assign(obj, { [$(el).text()]: $(el).next().text() }), {}));

console.log(myArray);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

1 Comment

many thanks .your code worked like a charm. I didn't know that we need two loops.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.