Javascript add object to an oustide array in a loop - javascript

I'm trying to add dynamically created Javascript object to an array. I could traverse the DOM & creating the objects. But when displaying the final array of Objects, the count is correct but all objects are of same value ie, final index value. How to get rid of this problem?
PS: DOM traversal & other functionalities work well & only problem with creating the final array of objects with correct values.
Javascript Code.
var match = {};
var matches = [];
$('.SIsort').each(function (i, v) {
console.log("type.."+typeof matches);
var date = $(this).find('td:eq(0)').find('meta')[0].content;
var team1 = $(this).find('td:eq(1)').find('div:eq(1)').text();
var team2 = $(this).find('td:eq(1)').find('div:eq(3)').text();
var loc = $(this).find('td:eq(2)').find('div:eq(0)').text();
match.date = date;
match.team1 = team1;
match.team2 = team2;
match.venue = loc;
console.log(match); // It displays Correctly
(matches = window.matches || []).push({});
matches = (window.matches || []).push(match);
// console.log(matches[i])
});
console.log(matches); // All object values belong only to final index

You're repeatedly pushing the same object into the array.
Move your
var match = {};
...line into the loop so that you create a new object each time.
Also, I'm not sure what you're trying to achieve with this:
(matches = window.matches || []).push({});
matches = (window.matches || []).push(match);
But you just want:
matches.push(match);
Here's a minimal example of what you're doing:
var match = {};
var i;
for (i = 0; i < 5; ++i) {
match.i = i; // Overwrites the previous `i` value on subsequent loops
matches.push(match); // Pushes the *same object* onto the array
}
console.log(matches); // Shows the same object, all with `i = 4`
Instead, create a new object each time:
var i;
for (i = 0; i < 5; ++i) {
var match = {}; // Creates a new object
match.i = i;
matches.push(match);
}
console.log(matches);
Applying that to your code:
var matches = [];
$('.SIsort').each(function (i, v) {
console.log("type.."+typeof matches);
var date = $(this).find('td:eq(0)').find('meta')[0].content;
var team1 = $(this).find('td:eq(1)').find('div:eq(1)').text();
var team2 = $(this).find('td:eq(1)').find('div:eq(3)').text();
var loc = $(this).find('td:eq(2)').find('div:eq(0)').text();
var match = {};
match.date = date;
match.team1 = team1;
match.team2 = team2;
match.venue = loc;
console.log(match); // It displays Correctly
matches.push(match);
});
console.log(matches);
Side note: These lines:
var match = {};
match.date = date;
match.team1 = team1;
match.team2 = team2;
match.venue = loc;
console.log(match); // It displays Correctly
matches.push(match);
can be combined into:
var match = {
date: date,
team1: team1,
team2: team2,
venue: loc
};
console.log(match); // It displays Correctly
matches.push(match);

The problem with your code is that you're creating only ONE instance of match outside of your loop and updating the same object in each iteration before adding it to your Array. Actually you're supposed to create a NEW object, every time you want to add an entry to your loop, so create a new object at the starting of the loop like below.
var matches = [];
$('.SIsort').each(function (i, v) {
var match = {};
// update match object and add to array
matches.push(match);
}
That should do it :)

Related

How to create key value pair using two arrays in JavaScript?

I have two arrays, keys and commonkeys.
I want to create a key-value pair using these two arrays and the output should be like langKeys.
How to do that?
This is array one:
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT']
This is array two:
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*']
This is the output I need:
var langKeys = {
'en-*': 'en_US',
'es-*': 'es_ES',
'pt-*': 'pt_PT',
'fr-*': 'fr_FR',
'de-*': 'de_DE',
'ja-*': 'ja_JP',
'it-*': 'it_IT',
'*': 'en_US'
};
You can use map() function on one array and create your objects
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT'];
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*'];
var output = keys.map(function(obj,index){
var myobj = {};
myobj[commonKeys[index]] = obj;
return myobj;
});
console.log(output);
JavaScript is a very versatile language, so it is possible to do what you want in a number of ways. You could use a basic loop to iterate through the arrays, like this:
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT']
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*']
var i;
var currentKey;
var currentVal;
var result = {}
for (i = 0; i < keys.length; i++) {
currentKey = commonKeys[i];
currentVal = keys[i];
result[currentKey] = currentVal;
}
This example will work in all browsers.
ES6 update:
let commonKeys = ['en-*', 'es-*', 'pt-*', 'fr-*', 'de-*', 'ja-*', 'it-*', '*'];
let keys = ['en_US', 'es_ES', 'pt_PT', 'fr_FR', 'de_DE', 'ja_JP', 'it_IT', 'en_US'];
let zipArrays = (keysArray, valuesArray) => Object.fromEntries(keysArray.map((value, index) => [value, valuesArray[index]]));
let langKeys = zipArrays(commonKeys, keys);
console.log(langKeys);
// let langKeys = Object.fromEntries(commonKeys.map((val, ind) => [val, keys[ind]]));
What you want to achieve is to create an object from two arrays. The first array contains the values and the second array contains the properties names of the object.
As in javascript you can create new properties with variales, e.g.
objectName[expression] = value; // x = "age"; person[x] = 18,
you can simply do this:
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT'];
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*'];
var langKeys = {};
var i;
for (i=0; i < keys.length; i++) {
langKeys[commonKeys[i]] = keys[i];
}
EDIT
This will work only if both arrays have the same size (actually if keys is smaller or same size than commonKeys).
For the last element of langKeys in your example, you will have to add it manually after the loop.
What you wanted to achieve was maybe something more complicated, but then there is missing information in your question.
Try this may be it helps.
var langKeys = {};
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT']
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*']
function createArray(element, index, array) {
langKeys[element]= keys[index];
if(!keys[index]){
langKeys[element]= keys[index-(commonKeys.length-1)];
}
}
commonKeys.forEach(createArray);
console.info(langKeys);
Use a for loop to iterate through both of the arrays, and assign one to the other using array[i] where i is a variable representing the index position of the value.
var keys = ['en_US', 'es_ES', 'pt_PT', 'fr_FR', 'de_DE', 'ja_JP', 'it_IT'];
var commonKeys = ['en-*', 'es-*', 'pt-*', 'fr-*', 'de-*', 'ja-*', 'it-*', '*'];
var langKeys = {};
for (var i = 0; i < keys.length; i++) {
var commonkey = commonKeys[i];
langKeys[commonkey] = keys[i];
}
console.log(JSON.stringify(langKeys));
let keys = ['en_US', 'es_ES', 'pt_PT', 'fr_FR', 'de_DE', 'ja_JP', 'it_IT'];
let commonKeys = ['en-*', 'es-*', 'pt-*', 'fr-*', 'de-*', 'ja-*', 'it-*', '*'];
// declaration of empty object where we'll store the key:value
let result = {};
// iteration over first array to pick up the index number
for (let i in keys) {
// for educational purposes, showing the number stored in i (index)
console.log(`index number: ${i}`);
// filling the object with every element indicated by the index
// objects works in the basis of key:value so first position of the index(i)
// will be filled with the first position of the first array (keys) and the second array (commonKeys) and so on.
result[keys[i]] = commonKeys[i];
// keep in mind that for in will iterate through the whole array length
}
console.log(result);

Split an array cause an error: not a function

I want to split an array that already have been split.
var string = '2016-08-08,63|2016-08-07,67|2016-08-06,64|2016-08-05,53|2016-08-04,63';
var array_dt = string.split(',');
var array_s = array_dt.split('|');
console.log(array_s);
That code returns TypeError: array_dt.split is not a function.
I'm guessing that split() can not split an array. Have I wrong?
Here's how I want it to look like. For array_dt: 2016-08-08,2016-08-07,2016-08-06,2016-08-05,2016-08-04. For array_s: 63,67,64,53,63. I will use both variables to a chart (line) so I can print out the dates for the numbers. My code is just as example!
How can I accomplish this?
Demo
If you want to split on both characters, just use a regular expression
var string = '2016-08-08,63|2016-08-07,67|2016-08-06,64|2016-08-05,53|2016-08-04,63';
var array_dt = string.split(/[,|]/);
console.log(array_dt)
This will give you an array with alternating values, if you wanted to split it up you can do
var string = '2016-08-08,63|2016-08-07,67|2016-08-06,64|2016-08-05,53|2016-08-04,63';
var array_dt = string.split(/[,|]/);
var array1 = array_dt.filter( (x,i) => (i%2===0));
var array2 = array_dt.filter( (x,i) => (i%2!==0));
console.log(array1, array2)
Or if you want to do everything in one go, you could reduce the values to an object
var string = '2016-08-08,63|2016-08-07,67|2016-08-06,64|2016-08-05,53|2016-08-04,63';
var array = string.split(/[,|]/).reduce(function(a,b,i) {
return a[i%2===0 ? 'dates' : 'numbers'].push(b), a;
}, {numbers:[], dates:[]});
console.log(array)
If performance is important, you'd revert to old-school loops, and two arrays
var string = '2016-08-08,63|2016-08-07,67|2016-08-06,64|2016-08-05,53|2016-08-04,63';
var array = string.split(/[,|]/);
var array1 = [];
var array2 = [];
for (var i = array.length; i--;) {
if (i % 2 === 0) {
array1.push(array[i]);
} else {
array2.push(array[i]);
}
}
console.log(array1, array2)
var string = '2016-08-08,63|2016-08-07,67|2016-08-06,64|2016-08-05,53|2016-08-04,63';
var array_dt = [];
var array_s = [];
string.split('|').forEach(function(el){
var temp = el.split(",");
array_dt.push(temp[0]);
array_s.push(temp[1]);
});
console.log(array_dt);
console.log(array_s);
Just do it one step at a time - split by pipes first, leaving you with items that look like 2016-08-08,63. Then for each one of those, split by comma, and insert the values into your two output arrays.
var string = '2016-08-08,63|2016-08-07,67|2016-08-06,64|2016-08-05,53|2016-08-04,63';
var arr = string.split("|");
var array_dt = [];
var array_s = [];
arr.forEach(function(item) {
var x = item.split(",");
array_dt.push(x[0]);
array_s.push(x[1]);
});

Split string into array by several delimiters

Folks,
I have looked at underscore.string and string.js modules and still can't find a good way to do the following:
Suppose I have a query string string:
"!dogs,cats,horses!cows!fish"
I would like to pass it to a function that looks for all words that start with !, and get back an Array:
['dogs','cows','fish']
Similarly, the same function should return an array of words that start with ,:
['cats','horses]
Thanks!!!
You can use RegEx to easily match the split characters.
var string = "!dogs,cats,horses!cows!fish";
var splitString = string.split(/!|,/);
// ["dogs", "cats", "horses", "cows", "fish"]
The only issue with that is that it will possibly add an empty string at the beginning of the array if you start it with !. You could fix that with a function:
splitString.forEach(function(item){
if(item === ""){
splitString.splice(splitString.indexOf(item), 1)
}
});
EDIT:
In response to your clarificaiton, here is a function that does as you ask. It currently returns an object with the values commas and exclaim, each with an array of the corresponding elements.
JSBin showing it working.
function splitString(str){
var exclaimValues = [];
var expandedValues = [];
var commaValues = [];
var needsUnshift = false;
//First split the comma delimited values
var stringFragments = str.split(',');
//Iterate through them and see if they contain !
for(var i = 0; i < stringFragments.length; i++){
var stringValue = stringFragments[i];
// if the value contains an !, its an exclaimValue
if (stringValue.indexOf('!') !== -1){
exclaimValues.push(stringValue);
}
// otherwise, it's a comma value
else {
commaValues.push(stringValue);
}
}
// iterate through each exclaim value
for(var i = 0; i < exclaimValues.length; i++){
var exclaimValue = exclaimValues[i];
var expandedExclaimValues = exclaimValue.split('!');
//we know that if it doesn't start with !, the
// the first value is actually a comma value. So move it
if(exclaimValue.indexOf('!') !== 0) commaValues.unshift(expandedExclaimValues.shift());
for(var j = 0; j < expandedExclaimValues.length; j++){
var expandedExclaimValue = expandedExclaimValues[j];
//If it's not a blank entry, push it to our results list.
if(expandedExclaimValue !== "") expandedValues.push(expandedExclaimValue);
}
}
return {comma: commaValues, exclaim: expandedValues};
}
So if we do:
var str = "!dogs,cats,horses!cows!fish,comma!exclaim,comma2,comma3!exclaim2";
var results = splitString(str)
results would be:
{
comma: ["comma3", "comma", "horses", "cats", "comma2"],
exclaim: ["dogs", "cows", "fish", "exclaim", "exclaim2"]
}

Extract specific substring using javascript?

If I have the following string:
mickey mouse WITH friend:goofy WITH pet:pluto
What is the best way in javascript to take that string and extract out all the "key:value" pairs into some object variable? The colon is the separator. Though I may or may not be able to guarantee the WITH will be there.
var array = str.match(/\w+\:\w+/g);
Then split each item in array using ":", to get the key value pairs.
Here is the code:
function getObject(str) {
var ar = str.match(/\w+\:\w+/g);
var outObj = {};
for (var i=0; i < ar.length; i++) {
var item = ar[i];
var s = item.split(":");
outObj[s[0]] = s[1];
}
return outObj;
}
myString.split(/\s+/).reduce(function(map, str) {
var parts = str.split(":");
if (parts.length > 1)
map[parts.shift()] = parts.join(":");
return map;
}, {});
Maybe something like
"mickey WITH friend:goofy WITH pet:pluto".split(":")
it will return the array, then Looping over the array.
The string pattern has to be consistent in one or the other way atleast.
Use split function of javascript and split by the word that occurs in common(our say space Atleast)
Then you need to split each of those by using : as key, and get the required values into an object.
Hope that's what you were long for.
You can do it this way for example:
var myString = "mickey WITH friend:goofy WITH pet:pluto";
function someName(str, separator) {
var arr = str.split(" "),
arr2 = [],
obj = {};
for(var i = 0, ilen = arr.length; i < ilen; i++) {
if ( arr[i].indexOf(separator) !== -1 ) {
arr2 = arr[i].split(separator);
obj[arr2[0]] = arr2[1];
}
}
return obj;
}
var x = someName(myString, ":");
console.log(x);

How to parse bracket tag on Javascript

I have tag like this, how the best way to get every key and value of those attribute and populate it within an array (number of attribute will be increasing)?
myData = '[data attr1="value1" attr2="value2" attr3="value3"]';
and get result array :
var arr = new Array();
arr['attr1'] = "value1";
arr['attr2'] = "value2";
arr['attr3'] = "value3";
and so on...
This probably does what you want, though it assumes that tag is already in the format you have described, i.e. a singular occurrence of [data ... ].
Also, the regular expression is purely based on what I've seen in your question; not sure whether it will break on other strings.
function decode(tag)
{
var r = /(\w+)="([^"]*)"/g,
h = {};
while ((m = r.exec(tag)) !== null) {
h[m[1]] = m[2];
}
return h;
}
Since you have string key in the data, use jquery object instead of array.
var arr = {};
var str = '[data attr1="value1" attr2="value2" attr3="value3"]​​​';
var n = str.split('[data ');
var str_arr = n[1].replace(']','').split(" ");
jQuery.each(str_arr,function(val){
var x = str_arr[val].split('=');
arr[x[0]] = x[1].replace('"','').slice(0,-1);
});
console.log(arr);
Try this code. It may help you.
Here is the DEMO
Though it can be more optimized if you put some more details about your code.
var tagRe = /\[(\w+)((?:\s+\w+="[^"]{0,50}")*)\s*]/g;
var attrRe = /\b(\w+)="([^"]*)"/g;
function parse(text) {
var result = [];
tagRe.lastIndex = 0; // reset start position
var tagMatch = tagRe.exec(text);
while (tagMatch) {
var currentTag = { 'name': tagMatch[1], 'attrs': {} };
var attrString = tagMatch[2];
attrRe.lastIndex = 0;
var attrMatch = attrRe.exec(attrString);
while (attrMatch) {
var attrName = attrMatch[1];
var attrValue = attrMatch[2];
currentTag.attrs[attrName] = attrValue;
attrMatch = attrRe.exec(attrString); // next match
}
result.push(currentTag);
tagMatch = tagRe.exec(text);
}
return result;
}
parse('[data attr1="value1" attr2="value2" attr3="value3"]');
> [{name:'data',attrs:{attr1:'value1',attr2:'value2',attr3:'value3'}}]
This works for any number of tags in the string. The name of the tag does not matter.

Categories

Resources