Dynamically building array, appending values - javascript

i have a bunch of options in this select, each with values like:
context|cow
context|test
thing|1
thing|5
thing|27
context|beans
while looping through the options, I want to build an array that checks to see if keys exist, and if they don't they make the key then append the value. then the next loop through, if the key exists, add the next value, comma separated.
the ideal output would be:
arr['context'] = 'cow,test,beans';
arr['thing'] = '1,5,27';
here's what i have so far, but this isn't a good strategy to build the values..
function sift(select) {
vals = [];
$.each(select.options, function() {
var valArr = this.value.split('|');
var key = valArr[0];
var val = valArr[1];
if (typeof vals[key] === 'undefined') {
vals[key] = [];
}
vals[key].push(val);
});
console.log(vals);
}

Existing code works by changing
vals=[];
To
vals={};
http://jsfiddle.net/BrxuM/

function sift(select) {
var vals = {};//notice I made an object, not an array, this is to create an associative array
$.each(select.options, function() {
var valArr = this.value.split('|');
if (typeof vals[valArr[0]] === 'undefined') {
vals[valArr[0]] = '';
} else {
vals[valArr[0]] += ',';
}
vals[valArr[0]] += valArr[1];
});
}
Here is a demo: http://jsfiddle.net/jasper/xtfm2/1/

How about an extensible, reusable, encapsulated solution:
function MyOptions()
{
var _optionNames = [];
var _optionValues = [];
function _add(name, value)
{
var nameIndex = _optionNames.indexOf(name);
if (nameIndex < 0)
{
_optionNames.push(name);
var newValues = [];
newValues.push(value);
_optionValues.push(newValues);
}
else
{
var values = _optionValues[nameIndex];
values.push(value);
_optionValues[nameIndex] = values;
}
};
function _values(name)
{
var nameIndex = _optionNames.indexOf(name);
if (nameIndex < 0)
{
return [];
}
else
{
return _optionValues[nameIndex];
}
};
var public =
{
add: _add,
values: _values
};
return public;
}
usage:
var myOptions = MyOptions();
myOptions.add("context", "cow");
myOptions.add("context","test");
myOptions.add("thing","1");
myOptions.add("thing","5");
myOptions.add("thing","27");
myOptions.add("context","beans");
console.log(myOptions.values("context").join(","));
console.log(myOptions.values("thing").join(","));
working example: http://jsfiddle.net/Zjamy/

I guess this works, but if someone could optimize it, I'd love to see.
function updateSiftUrl(select) { var
vals = {};
$.each(select.options, function() {
var valArr = this.value.split('|');
var key = valArr[0];
var val = valArr[1];
if (typeof vals[key] === 'undefined') {
vals[key] = val;
return;
}
vals[key] = vals[key] +','+ val;
});
console.log(vals);
}

Would something like this work for you?
$("select#yourselect").change(function(){
var optionArray =
$(":selected", $(this)).map(function(){
return $(this).val();
}).get().join(", ");
});
If you've selected 3 options, optionArray should contain something like option1, option2, option3.

Well, you don't want vals[key] to be an array - you want it to be a string. so try doing
if (typeof vals[key] === 'undefined') {
vals[key] = ';
}
vals[key] = vals[key] + ',' + val;

Related

Delete duplicate object(JSON) nodes - JavaScript

I have a JSON string:
var jsn = '{"header-v1":{"archives":{"is_author":"all"}},"header-v4":{"archives":{"is_author":"all"}}}';
This object is constantly updated and I want to remove duplicate values. For example, if it is:
var jsn = '{"header-v4":{"archives":{"is_author":"all"}}}';
And if the new rule set which should be added will be equal to
"header-v1":{"archives":{"is_author":"all"}}
then I want to remove "header-v4":{"archives":{"is_author":"all"}} from there, because there is a duplicate of {"archives":{"is_author":"all"}}.
Is that even possible with JavaScript?
var result = [];
$.each(subservices, function (i, e) {
var matchingItems = $.grep(result, function (item) {
return item.name === e.name && item.label === e.label;
});
if (matchingItems.length === 0){
result.push(e);
}
});
//displays result [{"name":"hello","label":"world"},{"name":"abc","label":"xyz"}]
alert(JSON.stringify(result));
JS fiddel
http://jsfiddle.net/defujjhp/
Maybe something like this you can do
var jsn = '{"header-v4":{"archives":{"is_author":"all"}}}';
var jsonObject = JSON.parse(jsn);
var newJsn = '{header-v1":{"archives":{"is_author":"all"}}}';
var newJsonObject = JSON.parse(newJsn);
var matchingKey = [];
Object.keys(newJsonObject).forEach(key => {
Object.keys(jsonObject).forEach(nkey => {
if(newJsonObject[key].toString() === jsonObject[nkey].toString()) {
matchingKey.push(nkey);
}
});
});
matchingKey.forEach(mkey => {
delete jsonObject[mkey];
});

Convert string to object hierarchy

I have the following string returned from an API and I want to convert it to an object hierarchy using javascript.
The string received is:
"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"
I want to convert it to a javascript object like:
{
paymentInfoList: {
PaymentInfo: [{
receiver: {
amount: 12.0
}
}]
}
}
I could write my own parser but wonder if there is some code already out there.
Update
Based on the answer from #JasonCust here is a parser to parse a full response from the PayPal Adaptive Payments Pay method:
https://github.com/danielflippance/paypal-ap-parser
I don't know of an existing parser that handles that format. Maybe something on Paypal's developer site? If you roll your own you could do so using a recursive function like the example below. I haven't tested it thoroughly but it's a POC that it's easy enough to do.
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
var arrayRegExp = /^(\w+)\((\d+)\)$/;
var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
var pair = input.split(':').map(function (str) { return str.replace(/"/g, ''); });
var newObj = setObjVal({}, pair[0].split('.'), pair[1]);
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
Alternatively if you want to use lodash you could use _.set():
var newObj = _.set({}, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
var pair = input.split(':').map(function (str) { return str.replace(/"/g, ''); });
var newObj = _.set({}, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>
Since I can't resist a little puzzle, here's a clean recursive solution that works for the input you've given (scroll down and view the snippet for a little playground):
function objectFromExpression(expression, value) {
if (!expression) {
return value;
}
var obj = {};
var matchKeyIdxRest = /^(\w+)(?:\((\d+)\))?(?:\.(.+))?$/;
var matches = expression.match(matchKeyIdxRest);
if (!matches) {
throw new Error('Oops! There\'s a problem with the expression at "' + expression + '"');
}
var key = matches[1];
var idx = matches[2];
var rest = matches[3];
var next = objectFromExpression(rest, value);
if (idx) {
var arr = [];
arr[ parseInt(idx) ] = next;
obj[key] = arr;
} else {
obj[key] = next;
}
return obj;
}
function keyValueExpressionToKeyValue(str) {
var matchKeyVal = /^"([^"]+)":"([^"]+)"$/;
var matches = str.match(matchKeyVal);
if (!matches) {
throw new Error('Oops! Couldn\'t extract key and value from input!');
}
return matches.slice(1);
}
var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
var keyAndValue = keyValueExpressionToKeyValue(input);
var key = keyAndValue[0]; // => paymentInfoList.paymentInfo(0).receiver.amount
var value = keyAndValue[1]; // => 12.00
objectFromExpression(key, value);
// => { paymentInfoList:
// { paymentInfo:
// [ { receiver:
// { amount: "12.00" }
// }
// ]
// }
// }
function objectFromExpression(expression, value) {
if (!expression) {
return value;
}
var obj = {};
var matchKeyIdxRest = /^(\w+)(?:\((\d+)\))?(?:\.(.+))?$/;
var matches = expression.match(matchKeyIdxRest);
if (!matches) {
throw new Error('Oops! There\'s a problem with the expression at "' + expression + '"');
}
var key = matches[1];
var idx = matches[2];
var rest = matches[3];
var next = objectFromExpression(rest, value);
if (idx) {
var arr = [];
arr[ parseInt(idx) ] = next;
obj[key] = arr;
} else {
obj[key] = next;
}
return obj;
}
function keyValueExpressionToKeyValue(str) {
var matchKeyVal = /^"([^"]+)":"([^"]+)"$/;
var matches = str.match(matchKeyVal);
if (!matches) {
throw new Error('Oops! Couldn\'t extract key and value from input!');
}
return matches.slice(1);
}
var inputEl = document.getElementById('input');
function onKeyUp() {
var outputEl = document.getElementById('output');
var input = inputEl.value.trim();
try {
var keyAndValue = keyValueExpressionToKeyValue(input);
var key = keyAndValue[0];
var value = keyAndValue[1];
var output = objectFromExpression(key, value);
outputEl.value = JSON.stringify(output, null, 2);
} catch (ex) {
outputEl.value = ex.toString();
}
}
inputEl.addEventListener('keyup', onKeyUp);
inputEl.dispatchEvent(new Event('keyup'));
label, textarea, input { display: block; }
label { font-family: sans-serif; }
input, textarea { font-family: monospace; width: 100%; margin-bottom: 1em; }
textarea { height: 15em; }
<label for="input">Input (type to see changes)</label>
<input id="input" value='"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"'/>
<label for="output">Output</label>
<textarea id="output">Click the "Parse!" button!</textarea>

Find array value

My array:
var PrivateChatList = [];
And push key and value (just example):
PrivateChatList['supporter1'] = 'player1';
PrivateChatList['supporter2'] = 'player2';
PrivateChatList['supporter3'] = 'player3';
PrivateChatList['supporter4'] = 'player4';
PrivateChatList['supporter5'] = 'player5';
PrivateChatList['supporter6'] = 'player6';
PrivateChatList['supporter7'] = 'player7';
I want to find "player4" key on function. How can i find ?
function getObjectKeyFromValue(object, value)
{
for(var k in object)
{
if(object[k] == value)
{
return k;
}
}
return '';
}
var key = getObjectKeyFromValue(PrivateChatList, 'player4')
alert(key); // 'supporter4'

how to reindex object start from 0

I have an object output from below code how to set the index start from 0 in js?
Object
3: Object
id: 34
type: 0
var obj = {};
var edited = false;
for (var i = 0; i < $(".list").length; i++) {
var data_id = parseInt($(".list").eq(i).attr('data-id'));
var data_type = parseInt($(".list").eq(i).attr('data-type'));
if ((data_type != 0)) {
edited = true;
} else {
edited = false;
}
if (edited == true) {
obj[i] = {};
obj[i]['id'] = data_id;
obj[i]['type'] = data_type;
}
}
console.log(obj);
Needs more jQuery ?
var arr = $(".list").filter(function() {
return $(this).data('type') != 0;
}).map(function() {
return { id : $(this).data('id'), type : $(this).data('type') };
}).get();
FIDDLE
Actually if you want to start in 0, use another variable and not "i" (which I think is 3 when you use it as index).
var obj = {};
var edited = false;
var obj_idx = 0;
for (var i = 0; i < $(".list").length; i++) {
var data_id = parseInt($(".list").eq(i).attr('data-id'));
var data_type = parseInt($(".list").eq(i).attr('data-type'));
if ((data_type != 0)) {
edited = true;
} else {
edited = false;
}
if (edited == true) {
obj[obj_idx] = {};
obj[obj_idx]['id'] = data_id;
obj[obj_idx]['type'] = data_type;
obj_idx += 1;
}
}
console.log(obj);
I think this time obj will be something like:
Object
0: Object
id: 34
type: 0
you could fake object as array by Array.prototype.push.call, in that way you could also gain the side effect: obj.length. it's kinda ninja and elegant :]
var obj = {};
var edited = false;
for (var i = 0; i < $(".list").length; i++) {
var data_id = parseInt($(".list").eq(i).attr('data-id'));
var data_type = parseInt($(".list").eq(i).attr('data-type'));
if ((data_type != 0)) {
edited = true;
} else {
edited = false;
}
if (edited == true) {
Array.prototype.push.call(obj, {id: data_id, type: data_type});
}
}
I am going to give a very simple and readable example. Say you've got an object with the following structure:
Object
0: Object
key: 'some-key'
value: 'some-value'
1: Object
...
Then you might want to delete an entry from it and reindex the whole thing, this is how I do it:
// obj is Object from above
const reIndexed = Object.entries(obj).map((element, index) => {
if (parseInt(element[0] != index) {
element[0] = index.toString();
}
return element;
});

overwriting a property in a string

Is there someone out there who can help me with this function. What it suppose to do is set a property in a string and this string is split firstly by a colon (:) for each control and the it checks if there is an id matching and if there is it then checks if there is a property matching if there is a property overwrite the value but my function doesn't seem to overwrite the property it just returns the original string. can someone help
var cookieValue = 'id=1&state=normal&theme=purple:id=2&state=maximized&theme=pink:id=3&state=maximized&theme=black';
var setProperties = function (cookie, id, prop, prop_value) {
var windows = cookie.split(':');
var result = $.each(windows, function(index, value) {
var temp1 = [];
if(value.indexOf(id) > -1) {
var temp2 = [];
var properties = value.split('&');
var result2 = $.each(properties, function(index, value) {
if(value.indexOf(prop) > -1) {
temp3 = [];
temp3 = value.split('=');
temp3[1] = prop_value;
temp2.push(temp3.join('='));
}else {
temp2.push(value);
}
return temp2.join('&')
});
temp1.push(result2.join('&'));
return temp1
}
else{
temp1.push(value);
}
return temp1;
})
return alert(result.join(':'));
}
setProperties(cookieValue, '2', 'theme', 'black');
Try:
function setProperties(cookie, id , name, value) {
var sections = $.map(cookie.split(":"), function (section) {
var pairs, found = false;
if (section.indexOf("id=" + id) === 0) {
pairs = $.map(section.split("&"), function (pair) {
if (pair.indexOf(name + "=") === 0) {
found = true;
return name + "=" + value;
} else {
return pair;
}
});
if (!found) {
pairs.push(name + "=" + value);
}
return pairs.join("&");
} else {
return section;
}
});
return sections.join(":");
}
Each doesn't return a value. You had some semicolons missing I edited the code a little.
It's not production worthy but at least it returns the (partially) correct value.
You will have to figure out how to replace that value in the cookie. I think regex is the best approach or of course you can pass temp1 array between the function but you will have to re-factor your code quite a lot.
var cookieValue = 'id=1&state=normal&theme=purple:id=2&state=maximized&theme=pink:id=3&state=maximized&theme=black';
var setProperties = function (cookie, id, prop, prop_value) {
var windows = cookie.split(':');
var result = $.each(windows, function(index, value) {
var temp1 = [];
console.log('value' + value);
console.log('windows' + windows);
console.log(cookieValue);
if(value.indexOf(id) > -1) {
var temp2 = [];
var properties = value.split('&');
var windows = $.each(properties, function(index, value) {
if(value.indexOf(prop) > -1) {
temp3 = [];
temp3 = value.split('=');
temp3[1] = prop_value;
temp2.push(temp3.join('='));
}else {
temp2.push(value);
}
cookieValue = temp2.join('&');
});
temp1.push(temp2.join('&'));
cookieValue = temp1;
}
else{
temp1.push(value);
}
cookeValue = temp1;
})
console.log("new cookie" + cookieValue); // PRINTS new cookieid=2&state=maximized&theme=black
}
setProperties(cookieValue, '2', 'theme', 'black');

Categories

Resources