I've apologize if this is a trivial task, and I've also been googling and searching high and low for some solution I can get my head around but so far no dice. So anyways....
I have this:
var myList = "key1,value1,key2,value2"
And I want to populate a struct with this string so I can reference it like this:
alert(myList.key1) // displays value1
Thoughts? There's probably some way to do this with JQuery's .each() perhaps? I'm seriously lost either way! Maybe just because it's really late and I've been stumbling through familiarizing myself with JS and JQuery again after a long hiatus. Any help is appreciated!
Assuming you never have commas in the values, you could start by using split:
var parts = myList.split(",");// ["key1", "value1", ...]
From there you can just use a simple loop:
var obj = {};
for (var i = 0; i < parts.length; i+=2) obj[parts[i]] = parts[i + 1];
As this answer points out, you can also write the loop like this:
var obj = {};
while (parts.length) obj[parts.shift()] = parts.shift();
This is a neat way to write this, but behaves differently: after this loop, parts will be empty.
String.replace method is your first choice when it comes to string parsing tasks
var myList = "key1,value1,key2,value2"
var result = {}
myList.replace(/(\w+),(\w+)/g, function($0, $1, $2) {
result[$1] = $2
})
Related
I have a bunch of numbers coming back from an api. It looks like this
1,2,3,4,5,6
Now i'm only wanting the last digit to be displayed rather than all of them.
How would i go about doing this? I need to add .slice on the end but im not sure what to put in the ()
Thanks
Sam
try this
.slice(-1)[0]
or
.slice(-1).pop()
var str = "1,2,3,4,5,6";
var _lastNum = str.slice(-1*(str.length - str.lastIndexOf(",")-1)); // Will return 6;
By far, voids answer seems to be the most comfortable and shortest one. But if you attempt to use at least one of the numbers at any time again, you may use something like this:
var str = "1,2,3,4,5,6"
str = str.split(',')
var lastNum = str[str.length-1]
As RobG wrote, you could also do
var lastNum = str.pop()
In ExtJS, using an Ext.Array (after using Ext.Array.difference), I get a resulting array and would like to know the best way to check if the array is empty?
I did use theArray.length as one could do in javascript, but I'm wondering if there is a better way/faster to acheive that? (At first I thought that isEmpty would help but it seems to be working on object, not array)
You can easily add this to the Array prototype like this:
Array.prototype.isEmpty = function(){
return !this.length;
};
var a = ['a','b','c','d'];
var b = ['b','d','f','h'];
var c = Ext.Array.difference(a,b);
var d = [];
console.log(c.isEmpty(), d.isEmpty());
Hope it helps :)
I know there are a lot of questions about this, but I can't find the solution to my problem and have been on it for a while now. I have two sets of input fields with the same name, one for product codes, and one for product names. These input fields can be taken away and added to the DOM by the user so there can be multiple:
Here is what I have so far, although this saves it so there all the codes are in one array, and all the names in another:
var updatedContent = [];
var varCode = {};
var varName = {};
$('.productVariationWrap.edit input[name="varVariationCode[]"]')
.each(function(i, vali){
varCode[i] = $(this).val();
});
$('.productVariationWrap.edit input[name="varVariationName[]"]')
.each(function(i1, vali1){
varName[i1] = $(this).val();
});
updatedContent.push(varCode);
updatedContent.push(varName);
I am trying to get it so the name and code go into the same array. i.e. the code is the key of the K = V pair?
Basically so I can loop through a final array and have the code and associated name easily accessible.
I can do this in PHP quite easily but no luck in javascript.
EDIT
I want the array to look like:
[
[code1, name1],
[code2, name2],
[code3, name3]
];
So after I can do a loop and for each of the arrays inside the master array, I can do something with the key (code1 for example) and the associated value (name1 for example). Does this make sense? Its kind of like a multi-dimensional array, although some people may argue against the validity of that statement when it comes to Javascript.
I think it's better for you to create an object that way you can access the key/value pairs later without having to loop if you don't want to:
var $codes = $('.productVariationWrap.edit input[name="varVariationCode[]"]'),
$names = $('.productVariationWrap.edit input[name="varVariationName[]"]'),
updatedContent = {};
for (var i = 0, il = $codes.length; i < il; i++) {
updatedContent[$codes.get(i).value] = $names.get(i).value;
}
Now for example, updatedContent.code1 == name1, and you can loop through the object if you want:
for (var k in updatedContent) {
// k == code
// updatedContent[k] == name
}
Using two loops is probably not optimal. It would be better to use a single loop that collected all the items, whether code or name, and then assembled them together.
Another issue: your selectors look a little funny to me. You said that there can be multiple of these controls in the page, but it is not correct for controls to have duplicate names unless they are mutually exclusive radio buttons/checkboxes--unless each pair of inputs is inside its own ancestor <form>? More detail on this would help me provide a better answer.
And a note: in your code you instantiated the varCode and varName variables as objects {}, but then use them like arrays []. Is that what you intended? When I first answered you, i was distracted by the "final output should look like this array" and missed that you wanted key = value pairs in an object. If you really meant what you said about the final result being nested arrays, then, the smallest modification you could make to your code to make it work as is would look like this:
var updatedContent = [];
$('.productVariationWrap.edit input[name="varVariationCode[]"]')
.each(function(i, vali){
updatedContent[i] = [$(this).val()]; //make it an array
});
$('.productVariationWrap.edit input[name="varVariationName[]"]')
.each(function(i1, vali1){
updatedContent[i1].push($(this).val()); //push 2nd value into the array
});
But since you wanted your Code to be unique indexes into the Name values, then we need to use an object instead of an array, with the Code the key the the Name the value:
var updatedContent = {},
w = $('.productVariationWrap.edit'),
codes = w.find('input[name="varVariationCode[]"]'),
names = w.find('input[name="varVariationName[]"]');
for (var i = codes.length - 1; i >= 0; i -= 1) {
updatedContent[codes.get(i).val()] = names.get(i).val();
});
And please note that this will produce an object, and the notation will look like this:
{
'code1': 'name1',
'code2': 'name2',
'code3': 'name3'
};
Now you can use the updatedContent object like so:
var code;
for (code in updatedContent) {
console.log(code, updatedContent[code]); //each code and name pair
}
Last of all, it seems a little brittle to rely on the Code and Name inputs to be returned in the separate jQuery objects in the same order. Some way to be sure you are correlating the right Code with the right Name seems important to me--even if the way you're doing it now works correctly, who's to say a future revision to the page layout wouldn't break something? I simply prefer explicit correlation instead of relying on page element order, but you may not feel the need for such surety.
I don't like the way to solve it with two loops
var updatedContent = []
$('.productVariationWrap.edit').each(function(i, vali){
var $this = $(this)
, tuple = [$this.find('input[name="varVariationCode[]"]').val()
, $this.find('input[name="varVariationName[]"]').val()]
updatedContent.push(tuple)
});
I have something I am trying to accomplish.
I'd like to take an array built with AJAX/xml.
array[/word0/, /word1/, /word2/]
and put this into a form that could be used in a .match():
result = string.match(array)
I have tried using a for loop and stepping through the array using string.match(array[i]) to no avail.
Is there an easy way to do this?
Edit: You may have a syntax problem. The following is not valid syntax:
array[/word0/, /word1/, /word2/]
Something like this fixes it:
var regexps = [/word0/, /word1/, /word2/];
Original answer:
Javascript RegExps already do this. You're looking for:
var regexp = /word0|word1|word2/;
Assuming your list of matches comes back in the right format, you could achieve this like so:
var words = ["word0", "word1", "word2"];
var regexp = new Regexp(words.join("|"));
str.match(regexp);
http://jsfiddle.net/KALPh/
Your approach was fine. Here's my implementation:
var regexes = [/^def/, /^abc/],
testString = 'abcdef',
numRegexes = regexes.length;
for(var x=0;x<numRegexes;x++) {
alert(regexes[x].test(testString));
}
To initialize your array, use
var array = [/word0/, /word1/, /word2/];
Then you can use
str.match(array[i])
If your problem is the transmission in "AJAX/xml", then you'll need to build the regular expressions client side with new RegExp(somestring) where somestring might for example be "word0" : you can't embed a regex literal in XML.
I'm coming from working in PHP for many years and having trouble wrapping my head around creating some more complicated data structures in JS for objects that are integer IDed. I need to build an object the stores these simpler objects hierarchically keyed on their integer ids. So if I have the following objectes each of which has a unique integer id:
section, element, item, entry
in php I would do something like
$arr[$section_id][$element_id][$item_id][$entry_id] = $entry;
In javascript this does not work. I know I could technically wrap those IDs in quotes to force it but that seems like a bad idea. Similarly I could create an object and use the quoted integer approach but again that seems hacky.
Right now I am storing the data in regular integer indexed arrays and then using caolan's async detect to look up a particular member by ID. This works but seems extremely messy compared to the php equivalent. I'm hoping there's a cleaner way to do this in JS.
TIA!
since javascript cannot save an array with string index, i use these :
var namespace = function(name, separator, container){
var ns = name.split(separator || '.')
, o = container || window
, i = 0;
while (i++ < ns.length) o = o[ns[i - 1]] = o[ns[i - 1]] || {};
return o;
}
namespace(arr + '.' + section_id + '.' + element_id + '.' + item_id + '.' + entry_id) = entry;
// ex : namespace('arr.1.3.2.6') will product arr.1.3.2.6 object
This is a little ugly, but it will get you pretty close to what you want.
You can add a method to the JavaScript Array class like so:
Array.prototype.g = function(index) {
if (this[index] == undefined) {
this[index] = [];
}
return this[index];
}
Then, to set something you would do this:
var test = [];
test.g(5).g(7)[5] = 1;
Unfortunately, for the last entry you'd have to remember to use the regular notation to set the value.
You would retrieve it like you expect:
test[5][7][5]; //1
Obviously I just pulled g out of thin air, you could come up with your own function name.
Disclaimer: People tend to frown on extending the built in types using the prototype chain, but as far as I know most major frameworks no longer do this so unless you or some third party JS is using the same name to extend Array somewhere else you should be fine.