I have an array with items and I want to group them according the first letter but when I push the item to the array it shows empty "Array[0]" while there are clearly items in it.
Apparently I'm doing something wrong but i have no idea what.
var group = [];
var alphabetArray = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
alphabetArray.forEach(function(letter) {
group[letter] = group[letter] || [];
group[letter].push({
key: letter,
letter
});
});
console.log(group);
Arrays are designed to hold an ordered set of data represented by property names which are integers.
You are assigning property names which are letters.
Arrays are not designed to hold that kind of data and console.log doesn't display those properties for arrays.
Don't use an array. Use an object. Objects are designed to hold unordered data with arbitrary property names. If order matters, then you might want to use a Map instead.
You are looking to create an object instead of an array. Change the [] to {}
An Array expects an int as index, the object can take a string
var group = {}; // Object instead of Array
var alphabetArray = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
alphabetArray.forEach(function(letter) {
group[letter] = group[letter] || [];
group[letter].push({
key: letter,
letter
});
});
console.log(group);
I guess you want to transform each letter to structure. I f so, you need Array.map:
var alphabetArray = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
var group = alphabetArray.map(function(letter) {
return {
[letter]: letter
};
});
console.log(group);
Related
I have an array of values:
let myArray = [ 'Ifmanwas',
'meanttos',
'tayonthe',
'groundgo',
'dwouldha',
'vegivenu',
'sroots' ]
I want to print out a new value for each item in the array so that the first item is a collection of all the characters at the zero index, the second is a collection of all the characters at the 1 index position, ect...
So for instance, the output of the first array would be "Imtgdvs" (all the letters at ("0"), the second would be "fearwer" (all the letters at index "1") ect...
I am very lost on how to do this and have tried multiple different ways, any help is appreciated.
For this simple attempt I have created an array of all the letters for the first instance:
function convertToCode(box) {
let arr = [];
for (i = 0; i < box.length; i++) {
let counter = i;
let index = box[counter];
let letter = index.charAt(0);
arr.push(letter);
}
console.log(arr);
}
convertToCode(myArray)
Thanks
The main issue in your example is this: index.charAt(0);. This will always get the first character, whereas you need a nested loop.
You could use Array.map() in combination with Array.reduce(), like so:
let myArray = ['Ifmanwas','meanttos','tayonthe','groundgo','dwouldha','vegivenu','sroots'];
const result = Array.from(myArray[0]) //Create an array as long as our first string
.map((l,idx) => //Update each item in that array...
myArray.reduce((out,str) => str[idx] ? out+str[idx] : out, "") //to be a combination of all letters at index [idx] from original array
);
console.log(result);
Note that this uses the first string in the array to decide how many strings to make, as opposed to the longest string.
I want to sort an array by a split part of an array.
example_array = ["Zebra:Add","Pay:Cold","And:Vets","Jam:Back"]
I want to so it sorts it like this:
console.log(code here) // prints ["Zebra:Add","Jam:Back","Pay:Cold","And:Vets"]
Note: I want "Zebra:Add","Pay:Cold", etc to stay together. I just want it be sorted by the text after the ":".
From your comment on the question:
I can't even think of a solution
Break the problem into smaller pieces. You want to sort an array by a part of the strings in the array, so you need to figure out / look into
How to sort an array (you've done that, you've found the sort method)
How to isolate the part of the string you want to sort on
How to correctly compare strings for Array#sort
How to do #2 and #3 within the context of doing #1
Re #2, there are various ways to do that. You could find the : via String#indexOf and then use substring to get all characters after it. You could split the string on :, then use the second half (if you know there won't be more than one : in the string). Or you could use a regular expression to isolate everything after the first :.
For instance, someString.match(/:.*$/)[0] isolates all characters starting with the first :. (Including the : is harmless, but you could use .substring(1) if you don't want to include it.)
Re #3: Array#sort expects its callback to return a negative number if the first argument should come before the second, 0 if their order doesn't matter, or a positive number if the second should come before the first. String#localeCompare compares strings according to the current locale and returns exactly that information, so we want to use that.
Re #4: Array#sort accepts a callback function, so you could do all the string splitting and comparison in that callback. But since the callback will be called repeatedly, frequently with either the first or second argument being one that's already been checked before, for larger arrays doing it then may be inefficient. It may make more sense to do all the string splitting / isolation in advance, then do the sort, then get your desired result.
So:
The not-particularly-efficient way (which is fine for data sets like your small array) is to isolate the part you want to sort on within the sort callback:
var array = ["Zebra:Add","Pay:Cold","And:Vets","Jam:Back"];
array.sort(function(left, right) {
return left.match(/:.*$/)[0].localeCompare(right.match(/:.*$/)[0]);
});
var array = ["Zebra:Add","Pay:Cold","And:Vets","Jam:Back"];
array.sort(function(left, right) {
return left.match(/:.*$/)[0].localeCompare(right.match(/:.*$/)[0]);
});
console.log(array);
With ES2015+ syntax:
const array = ["Zebra:Add","Pay:Cold","And:Vets","Jam:Back"];
array.sort((left, right) =>
left.match(/:.*$/)[0].localeCompare(right.match(/:.*$/)[0])
);
const array = ["Zebra:Add","Pay:Cold","And:Vets","Jam:Back"];
array.sort((left, right) =>
left.match(/:.*$/)[0].localeCompare(right.match(/:.*$/)[0])
);
console.log(array);
If it's a massive array where doing those splits on every compare is problematic, you could map first, then sort, then unmap:
var array = /*...really big array...*/;
array =
array.map(function(entry) { return {full: entry, key: entry.match(/:.*$/)[0]};})
.sort(function(left, right) { return left.key.localeCompare(right.key); })
.map(function(entry) { return entry.full; });
var array = ["Zebra:Add","Pay:Cold","And:Vets","Jam:Back"];
array =
array.map(function(entry) { return {full: entry, key: entry.match(/:.*$/)[0]};})
.sort(function(left, right) { return left.key.localeCompare(right.key); })
.map(function(entry) { return entry.full; });
console.log(array);
With ES2015+ syntax:
let array = /*...really big array...*/;
array =
array.map(entry => ({full: entry, key: entry.match(/:.*$/)[0] }))
.sort((left, right) => left.key.localeCompare(right.key))
.map(entry => entry.full);
let array = ["Zebra:Add","Pay:Cold","And:Vets","Jam:Back"];
array =
array.map(entry => ({full: entry, key: entry.match(/:.*$/)[0] }))
.sort((left, right) => left.key.localeCompare(right.key))
.map(entry => entry.full);
console.log(array);
I like the simplicity of the previous answer, in comparison My approach is probably too wordy! But here goes...
1.) take the original array and build a new sorting array from it, JSON array with each object having a text1 and text2 value... we'll sort on the text 2 value
2.) run a sort based on the text2 value
3.) empty the original array
4.) loop over the sorting array and re-populate the original array
heres a fiddle example I threw together
// STARTING ARRAY. WE WANT TO SORT BY THE TEXT AFTER THE COLON
example_array = ["Zebra:Add", "Pay:Cold", "And:Vets", "Jam:Back"];
// AN EMPTY ARRAY TO BUILD A JSON ARRAY FROM, THE SORT FROM THE DESIRED TEXT STRING
sorting_array = [];
// LOOP THROUGH THE ORIGINAL ARRAY AND PUSH A NEW OBJECT TO THE SORTING ARRAY
// EACH OBJECT CONTAINS A TEXT1 VALUE AND A TEXT2 VALUE
$.each(example_array, function(i, val){
sorting_array.push({"text1": val.split(':')[0], "text2": val.split(':')[1]})
})
// SORT THE SORTING ARRAY BY THE TEXT2 VALUE
sorting_array.sort(function(a, b){
if (a.text2 < b.text2) return -1;
if (b.text2 < a.text2) return 1;
return 0;
});
// EMPTY OUR ORIGINAL ARRAY
example_array = [];
// FOR DEMO PURPOSES LETS DISPLAY EACH IN THE DOM IN A UL ,
// AND ALSO RE-POPULATE THE ORIGINAL ARRAY WITHT HE NEW ORDER
$.each(sorting_array, function(i, val){
example_array.push(val.text1+':'+val.text2)
})
// TO SHOW THE NEW ORDER, LETS LOOP BACK OVER THE EXAMPLE_ARRAY
$.each(example_array, function(i, val){
$('ul').append('<li>' + val+ '</li>');
})
When looking at set of characters I am trying to put each letter into a specifc order in an array. For Example: Given the Strings "cat" and "dog" I would want an array that contains [d,o,g,c,a,t], cat at the end of the array because it was read first.
Currently I have tried this:
However, when I try the code below assuming the strings are "cat" and "dog".
I get an array containing: [c,a,t,d,o,g]. Instead of push I have also tried .unshift but the array now reads: [g,o,d,t,a,c].
var chars = /^[a-z]$/;
var string = [];
function makeword(){
if(currentChar.match(chars)){
string.push(currentChar);
currentChar = getNextChar(); //Gets next Character in the String
makeword();
}
}
Is something like this possible in Javascript?
If I understood you correctly, you want to provide a list of strings, then have them show up in an array in reverse order, with each letter as an element of the array. The following function will do just that:
function makeWords() {
var arr = [];
for(var i = arguments.length - 1; i >=0; i--) {
arr.push(arguments[i]);
}
return arr.join('').split('');
}
so running makeWords('cat', 'dog') will result in ['d','o','g','c','a','t'].
It's a relatively simple code when a functional approach is used. The rest and spread operators are very handy both to collect the function arguments and to spread the characters of a word into an array.
var characterify = (...c) => c.reduceRight((a,b) => a.concat([...b]) ,[]);
document.write("<pre>" + JSON.stringify(characterify("cat","dog")) + "</pre>");
I have javascript objects that follow this pattern. Keys are to the left of the = sign, values to the right. The keys that are duplicates need to be concatenated to one key while keeping all the values.
var arrUnique = ['arTitle=randomword','arTitle=random','beTitle=rand1','bnTitle=whatever','caTitle=mango','caTitle=mangoes']
Becomes this string:
arTitle = ['randomword','random' ], beTitle = ['rand1'], bnTitle = ['whatever'], caTitle = ['mango','mangoes']
Here is where I am at so far. Create an object with all the keys using regex. Then create a regex construction which loops through each object in keys and pushes to x only when it matches more then 1.
var keys = (/\w{2}Title=/gi);
var x = [];
for (i = 0; i < arrUniqueCount; i++){
var regexp = new RegExp(keys[i], "gi");
var str2 = arrUniqueString.match(regexp).length;
if (str2 > 1){
x.push(regexp[i])}
}
alert("repeats: " + x);
Next I was thinking of using regex to replace and match etc to finally get my outcome. I am finding this stage difficult. Would anybody mind sharing a better way?
I would go the route of just sliptting at the '=' sign then adding them to an object based on the key at index position 0 of that split.
var arrUnique = ['arTitle=randomword', 'arTitle=random', 'beTitle=rand1', 'bnTitle=whatever', 'caTitle=mango', 'caTitle=mangoes'];
//object to collect the final result in
var result = {};
//go through each item and split on the equal
//this will create an array or arrays that contain your key/value
arrUnique.map(function(x) {
return x.split("=");
}).forEach(function(item) {
//if the key doesn;t yet exist in the object declare it as an empty array
if (!result[item[0]]) {
result[item[0]] = [];
}
//push the value onto this key
result[item[0]].push(item[1]);
});
console.log(result);
I have placed my frustrations into a jsfiddle to observe here: http://jsfiddle.net/8ShFr/1/
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
alert('why does this array have a length of ' + brand_new_array.length + '???');
I am doing some calculations client side that require me to set javascript array keys of 1M+ in number.
Not knowing exactly what that number is demands that I iterate through the first 1M+ empty array values before getting to an array key that holds data.
I simply want to set a single large key value for a javascript array without creating a bunch of empty keys before it?
I am using jQuery.each to iterate over the array, and it keeps going through array[0], array[1], array[2], etc... when I only set array[123125] for example.
Just filter out the undefineds.
brand_new_array = brand_new_array.filter(function(n){return n !== undefined});
The reason for the length being 10 is that an array's length is set to the largest index number in the array. However, this does not mean there are 9 other values in there because in javascript an array is at its base an object.
The length is just a property in the object. Arrays in javascript are at their core objects (Array Object 1). They merely act like arrays through an api.
"Whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index" 1
1. ECMAScript Language Specification 15.4 Array Objects
You probably want to just use an object with strings for keys (the keys can be the toString() of Numbers, which will happen automatically if you try to use numbers).
var sparse_array_obj = {};
sparse_array_obj[10003210234] = 4; // Fair dice roll
sparse_array_obj[5] = 17; // Truly random number
sparse_array_obj[900] = Math.random(); // Pseudorandom number
for(var i in sparse_array_obj)
console.log(sparse_array_obj[i]);
The downside is that Javascript provides no guarantees about the iteration order through an object (since its keys are unordered by definition). There are however ways around this, such as:
// Sort the keys in numeric order
var sorted_keys = Object.keys(sparse_array_obj).sort(function(a, b){ return a - b; });
for(var i = 0; i < sorted_keys.length; i++)
console.log(sparse_array_obj[sorted_keys[i]]);
Object.keys needs to be shimmed in older browsers.
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
var result = brand_new_array.filter(function(e) { return e != undefined;})[0];
alert(brand_new_array.indexOf(result));
Travis J is right. The array in your example only contains one entry, but your use of jQuery.each() is making you think there are 10 entries because it iterates from 0 up to the highest index number of the array (defines the length). This is from the jQuery.each() API documentation.
A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties.
Going back to your example:
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
This will result in only one console.log output:
for(var i in brand_new_array)
console.log(brand_new_array[i]);
This will result in 10 console.log outputs:
$(brand_new_array).each( function(i,e) { console.log(e) })
Similarly, this will result in 10 console.log outputs:
for (var i=0;i<brand_new_array.length;i++)
console.log(brand_new_array[i]);
If you really want to stick with using .each() then you can skip the undefined indices like so:
$(brand_new_array).each( function(i,e) {
if (this.hasOwnProperty(i)){ console.log(e) }
})
Filter the falsy items - including undifined:
var a=[1,2,"b",0,{},"",NaN,3,undefined,null,5];
var b=a.filter(Boolean); // [1,2,"b",{},3,5]
The length is 11 because the index starts at 0.
x[0] = undefined
x[1] = undefined
x[2] = undefined
x[3] = undefined
x[4] = undefined
x[5] = undefined
x[6] = undefined
x[7] = undefined
x[8] = undefined
x[9] = undefined
x[10] = "random array value"