I need to reformat the following JSON data
[
{
"name": "Hello",
"value": 1
},
{
"name": "Hello",
"value": 11
},
{
"name": "Bye",
"value": 2
},
{
"name": "Bye",
"value": 22
}
]
to this:
[
{
"Hello": 1,
"Bye": 2
},
{
"Hello": 11,
"Bye": 22
},
]
There will always be an object with the same "name" field (but a different value in the "value" field) right after. I am stuck and not sure how to solve this. Is it possible to do using Lodash or pure JavaScript?
I have never before heard of Lodash, but in pure JS this can be solved with two nested loops:
function myConvert(long)
{
var short = [];
for(var i = 0; i < long.length; i++)
{
var key = long[i].name;
var value = long[i].value;
var object = null;
for(var j = 0; j < short.length; j++)
{
if(short[j][key] === undefined)
{
object = short[j];
break;
}
}
if(object === null)
{
object = {};
short.push(object);
}
object[key] = value;
}
return short;
}
This is basically:
Iterate over all elements of long.
For each of those, iterate over all elements of short to find the first element where the current name as key is not defined.
Create a new object, if not found.
Add the current value to object with name as key.
Related
I have a table of data that is rendered from an object. Specifically, each row of the table is a value from the array.
I need to be able to move the object up or down in the array, depending on the button clicked.
var obj = [{
"RuleDetailID": "11624",
"AttributeValue": "172",
"Value": "Account Manager",
"IsValueRetired": "0"
}, {
"RuleDetailID": "11626",
"AttributeValue": "686",
"Value": "Agent",
"IsValueRetired": "0"
}, {
"RuleDetailID": "11625",
"AttributeValue": "180",
"Value": "Analyst",
"IsValueRetired": "0"
}, {
"RuleDetailID": "11629",
"AttributeValue": "807",
"Value": "Individual Contributor",
"IsValueRetired": "0"
}, {
"RuleDetailID": "11627",
"AttributeValue": "690",
"Value": "Senior Agent",
"IsValueRetired": "0"
}];
// Exmaple only, just rendering a table
function renderExample() {
var table = '';
for (var key in obj) {
table += "<tr><td>" + obj[key].Value + "</td><td>Move Up</td><td></td><td>Move Down</td></tr>";
}
return table;
}
// Move the object in the array up or down
function move(value, positionChange) {
// On run, move the object in the array up or down respectivly.
}
<table>
<tbody id="example">
<script>
document.write(renderExample())
</script>
</tbody>
</table>
Can this be done with something like lodash or is it more of a manual approach? I tried by getting the index of the clicked item and then doing +1 or -1 accordingly to give me the new index. However, I wasn't sure what to do at that point since another item would already exist at that index.
How can I go about achieving this? Not looking for a jQuery approach, javascript or a library such as lodash only.
You can use array.splice twice, first to remove the item you want to move, and then to insert it into the new position
var data = [1,2,3,4,5];
function moveItem(from, to) {
// remove `from` item and store it
var f = data.splice(from, 1)[0];
// insert stored item into position `to`
data.splice(to, 0, f);
}
moveItem(0, 2);
console.log(data);
You can also use an old-school swap mechanism:
function move(value, positionChange) {
// On run, move the object in the array up or down respectivly.
for (var i = 0; i < obj.length; i++) {
if (obj[i].RuleDetailID == positionChange) {
var newIndex = value === 'up' ? i - 1 : i + 1;
if (newIndex >= obj.length || newIndex < 0) return;
var temp = obj[i];
obj[i] = obj[newIndex];
obj[newIndex] = temp;
document.getElementById('example').innerHTML = renderExample();
}
}
}
var item = {"mtyp":2,"mtr":3,"qnt":51,"unt":"pint","nts":"cvbbcv"}
var data = [{"mtyp":"2","mtr":"2","qnt":"54","unt":"ml","nts":"ngvjn"},{"mtyp":"2","mtr":"3","qnt":"51","unt":"pint","nts":"cvbbcv"}]
output should be:
var data = [{"mtyp":"2","mtr":"2","qnt":"54","unt":"ml","nts":"ngvjn"}]
You can use below script that I have written to meet your requirement.
I am assuming that your JSON object will have similar key names at both end, if not then let me know I will update the script for you.
Your desired result will be available in resultdata.
<script type="text/javascript">
var item = { "mtyp": 2, "mtr": 3, "qnt": 51, "unt": "pint", "nts": "cvbbcv" }
var data = [{ "mtyp": "2", "mtr": "2", "qnt": "54", "unt": "ml", "nts": "ngvjn" }, { "mtyp": "2", "mtr": "3", "qnt": "51", "unt": "pint", "nts": "cvbbcv" }]
// Holds the result data.
var resultdata = [{}];
// Remove initialized result set.
resultdata.pop();
// Variable to hold comparison value.
var hasMatch = false;
// Loop through data values.
for (var index = 0; index < data.length; ++index) {
// Fetch current item.
var individualData = data[index];
// Compare item values with individual data values.
if (item.mtyp == individualData.mtyp &&
item.mtr == individualData.mtr &&
item.qnt == individualData.qnt &&
item.unt == individualData.unt &&
item.nts == individualData.nts) {
hasMatch = true;
}
else {
hasMatch = false;
}
// If then is no match then add to the result.
// ResultData will hold all the values that are not present in item.
if (!hasMatch)
{ resultdata.push(individualData); }
}
</script>
While the question is quite unclear, if you like to get a new array or an in situ (in place) solution, and despite some values does not match type wise, like
qnt: 51
and
qnt: "51"
I suggest to use a combination of Array#filter for the array itself and Object.keys with Array#every for checking all properties and get all items who not match.
var item = { mtyp: 2, mtr: 3, qnt: 51, unt: "pint", nts: "cvbbcv" },
data = [{ mtyp: "2", mtr: "2", qnt: "54", unt: "ml", nts: "ngvjn" }, { mtyp: "2", mtr: "3", qnt: "51", unt: "pint", nts: "cvbbcv" }];
data = data.filter(function (a) {
return !Object.keys(item).every(function (k) {
return a[k] == item[k];
});
});
console.log(data);
This question already has answers here:
How to determine equality for two JavaScript objects?
(82 answers)
Closed 7 years ago.
I'm trying to add one object to another object.
Let's say I have two objects. selectedItemObj and selectedItemQueue. I'd like to add the selectedItemObj to selecteditemQueue but ONLY if that selectedItemObject does not match any of the objects in selectedItemQueue
Let's say I have this object here:
var selecteditemObj = [
{
"market_hash_name":"Chroma 2 Case Key 1",
"assetid":"92700754417_143965972",
"amount":1,
"image":"https://steamcommunity-a.akamaihd.net/economy/image/-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXX7gNTPcUxuxpJSXPbQv2S1MDeXkh6LBBOie3rKFRh16PKd2pDvozixtSOwaP2ar7SlzIA6sEo2rHCpdyhjAGxr0A6MHezetG0RZXdTA/"
}];
var selectedItemQueue = [
{
"market_hash_name":"Chroma 2 Case Key 2",
"assetid":"92700754667_143865972",
"amount":1,
"image":"https://steamcommunity-a.akamaihd.net/economy/image/-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXX7gNTPcUxuxpJSXPbQv2S1MDeXkh6LBBOie3rKFRh16PKd2pDvozixtSOwaP2ar7SlzIA6sEo2rHCpdyhjAGxr0A6MHezetG0RZXdTA/"
},
{
"market_hash_name":"Shadow Case Key 3",
"assetid":"1293611210722_143865972",
"amount":1,
"image":"https://steamcommunity-a.akamaihd.net/economy/image/-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXX7gNTPcUxuxpJSXPbQv2S1MDeXkh6LBBOiePrKF4wi6aaIGwStN_jl4bSzvXwMO6AwDlSvsYoiOiZ8dij3QbtqkU9ZnezetFWWxusZg/"
},
{
"market_hash_name":"Shadow Case Key 4",
"assetid":"123393510722_143861972",
"amount":1,
"image":"https://steamcommunity-a.akamaihd.net/economy/image/-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXX7gNTPcUxuxpJSXPbQv2S1MDeXkh6LBBOiePrKF4wi6aaIGwStN_jl4bSzvXwMO6AwDlSvsYoiOiZ8dij3QbtqkU9ZnezetFWWxusZg/"
}
];
Here is my attempt of it, it adds to the queue but it doesn't check if the child object exists. How can I add that?
function addItemToSelectedQueue(assetId){
var itemObj = findItemById(assetId);
var queueHasItem = false;
for (var i = selectedItemQueue.length - 1; i >= 0; i--) {
if (selectedItemQueue[i] === itemObj) {
queueHasItem == true;
};
};
if (queueHasItem == false) {
selectedItemQueue.push(itemObj);
updateSelecteditems();
};
}
I would do it this way:
function addItemToSelectedQueue(fromobj, toobj){
var found = false;
for(var x=0; x<toobj.length; x++){
if(toobj[x].market_hash_name == fromobj[0].market_hash_name){
found = true;
}
}
if(found == false){
toobj.push(fromobj[0]);
}
}
Usage:
addItemToSelectedQueue(selecteditemObj, selectedItemQueue);
Works perfectly fine for me!
What about something like this #JsBIN? I assume market_hash_name is used to differential between each object.
var selecteditemObj = [
{
"market_hash_name":"Chroma 2 Case Key 1",
}
];
var selectedItemQueue = [
{
"market_hash_name":"Chroma 2 Case Key 2",
},
{
"market_hash_name":"Chroma 2 Case Key 3",
}
];
function addItemObjIfNotExist(obj1, obj2, id) {
for(var i = 0, len = obj2.length; i < len; i++) {
if(obj1[1][id] !== obj2[i][id]) {
obj2.push(obj1);
}
}
return obj2;
}
console.log(addItemObjIfNotExist(selectedItemQueue,selecteditemObj, 'market_hash_name'));
Output:
[[object Object] {
market_hash_name: "Chroma 2 Case Key 1"
}, [[object Object] {
market_hash_name: "Chroma 2 Case Key 2"
}, [object Object] {
market_hash_name: "Chroma 2 Case Key 3"
}]]
I am new to javascript & jquery, Need to remove an element from the below array structure
[{
"tag": "tag1",
"description": "description1"
}, {
"tag": "tag2",
"description": "description2"
}, {
"tag": "tag3",
"description": "description3"
}]
The element to be removed is known {"tag":"tag2", "description":"description2"}.
How can i find this element and remove from the array.
Please find the code which i am using to remove an element
var actionDic = [];
actionDic.push({
description: desc,
tag: tag
});
The actionDic array is populated as user enter text in textinput and selects 'add' option.
var deleterow = {
tag: "tag2",
description: "description2"
};
var index = $.inArray(deleterow, actionDic);
if (index != -1) {
actionDic.splice(index, 1);
}
The correct index is not obtained. Kindly let me know what wrong is in the code.
Thanks.
Since the comparison between the item to remove and each element in actionDic isn't trivial, you could use jQuery.grep():
actionDic = jQuery.grep(actionDic, function(elem) {
return elem.tag == deleterow.tag && elem.description == deleterow.description;
}, true);
Demo
It performs a search using a custom search function and returns the array elements that didn't match. The result replaces the previous value of actionDic and effectively removed that one item.
Update
Unfortunately, this method could be considered heavy because a new array gets created at each invocation; both in terms of what jQuery can do and standard JavaScript functionality, this particular feature is lacking. ECMAScript 6 will have the Array.prototype.find() method that will do the job of finding the index in an array (with which you can perform the splice).
You can of course write one yourself too:
(function($) {
$.find = function(arr, fn) {
for (var i = 0, len = arr.length; i < len; ++i) {
if (fn(arr[i], i, arr)) {
return i;
}
}
return -1;
};
}(jQuery));
var index = $.find(actionDic, function(elem) {
return elem.tag == deleterow.tag && elem.description == deleterow.description;
});
if (index != -1) {
actionDic.splice(index, 1);
}
Demo
I've implemented an indexOfObject method of Array prototype in one of my projects. It searches for an index of object by the given property name and value. Here it is:
Array.prototype.indexOfObject = function(searchTerm, property) {
for (var i = 0, l = this.length; i < l; i++) {
if (this[i][property] === searchTerm) {
return i;
}
}
return -1;
};
You can use this method to find the index of your object using a unique property. In your case you can use it like this:
var arr = [{
"tag": "tag1",
"description": "description1"
}, {
"tag": "tag2",
"description": "description2"
}, {
"tag": "tag3",
"description": "description3"
}], deleteObject = {
tag: "tag2",
description: "description2"
};
var index = arr.indexOfObject(deleteObject.tag, 'tag');
Then you can use that index to remove the object from the array:
if (index > -1) {
arr.splice(index, 1);
}
Here is the working example in JSFiddle.
var actionDic = [{
"tag": "tag1",
"description": "description1"
}, {
"tag": "tag2",
"description": "description2"
}, {
"tag": "tag3",
"description": "description3"
}]
var element = {"tag":"tag2", "description":"description2"}
for(var i=0;i<actionDic.length;i++) {
var found = false;
for(each in actionDic[i]) {
if(actionDic[i][each] == element[each]) {
found = true
} else {
found = false;
break;
}
}
if(found) {
actionDic.splice(i,1);
found=false;
}
}
This gets your inner array objects:
for (var x = 0; x < actionDic.length; x++){
var arrayItem = actionDic[x];
if (arrayItem["tag"] == "tag2"){
alert(arrayItem["description"]);
}
}
Working fiddle: http://jsfiddle.net/4khjp/
You can use underscore.js which contains many useful helpers for Objects, Arrays etc.
Removing array element:
array = _.reject(array, function(item) {
return item.tag == 'tag2'; // <- if tag is unique to whole array
});
I have a JSON array like below:
var jsonArray = [{"k1":"v1"},{"k2":"v2"},{"k3":"v3"},{"k4":"v4"},{"k5":"v5"}]
I don't know which keys does exists in this array.
I want to get all the existing key from the array.
It should be possible something like this:
for(i=0;i<jsonArray.lenght;i++){
// something like- key = jsonArray[i].key
// alert(key);
}
Please tell me the method or way to get all keys existing in Json array.
Regards
Why don't you use a
var jsonObject = {"k1":"v1","k2":"v2","k3":"v3","k4":"v4","k5":"v5"}
instead of your
var jsonArray = [{"k1":"v1"},{"k2":"v2"},{"k3":"v3"},{"k4":"v4"},{"k5":"v5"}]
? Then the solution would be so simple: Object.keys(jsonObject).
Try this:
var L = jsonArray.length;
for (var i = 0; i < L; i++) {
var obj = jsonArray[i];
for (var j in obj) {
alert(j);
}
}
I've also made some modifications of your current code (like length caching).
Loop through the object properties, and select the first "real" one (which given your data schema should be the only real one).
var jsonArray = [{"k1":"v1"},{"k2":"v2"},{"k3":"v3"},{"k4":"v4"},{"k5":"v5"}]
for (var i = 0; i < jsonArray.length; i++) {
for (var prop in jsonArray[i]) {
if (jsonArray[i].hasOwnProperty(prop)) {
var key = prop;
break;
}
}
alert(key);
}
See How to loop through items in a js object? for an explanation of why it's important to use hasOwnProperty here.
Try this:
jsonArray.reduce(function(keys, element){
for (key in element) {
keys.push(key);
}
return keys;
},[]);
This should also work for multiple keys in the array objects.
If you're supporting old browsers that don't have reduce and map, then consider using a shim.
var id = { "object": "page", "entry": [{ "id": "1588811284674233", "time": 1511177084837, "messaging": [{ "sender": { "id": "1393377930761248" }, "recipient": { "id": "1588811284674233" }, "timestamp": 1511177084553, "message": { "mid": "mid.$cAAX_9pLcfu1mCnGmiVf2Sxd2erI2", "seq": 1882, "text": "a" } }] }] };
function getKey(obj, data) {
//#author dvdieukhtn#gmail.com
var data = data || [];
if (obj) {
var keys = Object.keys(obj);
for (var pos in keys) {
console.log();
data.push(keys[pos]);
if ((obj[keys[pos]].constructor === Array)) {
for (var i = 0; i < obj[keys[pos]].length; i++) {
getKey(obj[keys[pos]][i], data);
}
}
else if (obj[keys[pos]].constructor === Object) {
getKey(obj[keys[pos]], data);
}
}
return data;
}
}
console.log(getKey(id));