Underscore: group arrays with common second index value? - javascript

I found _.groupBy which works on objects by setting the property you want to group by but failed to find one for grouping an array of arrays.
arrays = [[0,'A','01010'],[4,'CD','1111'],[9,'FF','01010'],[6,'AX','01010']]
.groupBy yields nothing. I want to group by the 3rd value in each array.
what if I wanted to group by the 1st and 3rd array value?

_.groupBy() works on arrays or objects and allows you to specify an iterator function.
So this would group by the 3rd value in each array:
_.groupBy(arrays, function(num){return num[2]});
demo fiddle
You could also use the 1st and 3rd values. Exactly how you do that depends on how you want to combine the 2 values. For instance this:
_.groupBy(arrays, function(num){return num[0]+'.'+num[2]});
Results in:
Object {0.01010: Array[1], 4.1111: Array[1], 9.01010: Array[1], 6.01010: Array[1]}
Given your data.
Or if you want to group by the third value and then group those results by the first value we can do this:
var out = _.groupBy(arrays, function(num){return num[2] });
out2={};
for (var prop in out) {
out2[prop] = _.groupBy(out[prop],function(num) {return num[0]});
}
Which, with this data:
arrays = [[0,'A','01010'],[4,'CD','1111'],[9,'FF','01010'],[6,'AX','01010'],[0,'AX','01010']]`
(so that we have a duplicate first entry) produces:
01010: Object 0: Array[2] 6:Array[1] 9: Array[1] 1111: Object 4: Array[1]
demo of that

Related

Unexpected Output from Array() Method

I have this snippet of code below and don't quite understand the output
function repeatStringNumTimes(str, num) {
if (num <0) {
return ""
} else {
return Array(num+1).join(str)
}
}
console.log(repeatStringNumTimes("abc", 3));
I would have expected the output to be "abcabcabc" though if I console.log(repeatStringNumTimes("abc", 3)) in JS Bin it produces "abcabc"?
If I specify Array(3) - Would it not concatenate the string 3 times? Why only 2 in this instance?
If I specify Array(3) - Would it not concatenate the string 3 times?
Why only 2 in this instance?
console.log([1,2,3].join('abc'))
// outputs 1abc2abc3
Note that 'abc' is the separator for the join between the 3 elements, and so it appears twice, not 3 times.
Therefore, if you create an empty array, it shows 'abc' twice, separating 3 empty strings:
console.log(Array(3).join('abc'))
// outputs abcabc
Also note that there is String.repeat()
console.log('abc'.repeat(3))
// outputs abcabcabc
look when i run your code the right output appears so your code has no bugs, and when you specify Array(3) the output will be "abcabc" your code is working well
If you will have a look into the Array#join documentation, It will join the array items based on the passed separator in the join method. Ideally, It will not consider the join before the first and after the last element in an array.
console.log(Array(3)) // [undefined, undefined, undefined]
console.log([undefined, undefined, undefined].join('abc')); // 'abcabc'
As you want to fill the array with the string, Correct method is Array#fill which changes all elements in an array to a static value, from a start index (default 0) to an end index (default array.length) and then join the elements from an array with the help of Array.join() method.
console.log(Array(3).fill('abc').join(''));

Store the indexes of random elements correctly in an array

I got an array a which is filled by node objects. For example I got 200 nodes on my screen and all are saved inside this array. These nodes are labeled by individual indexes a[0], a[1], ect. Now, when I select a number of random nodes (for example with shortest path) and store them in a second array b which looks like b = [ object, object, object, object.....],
is there a way to automatically return the position in array a? For example, when I click a random node, which is at the 3rd position in array a , that means at a[2], then I want that this position is returned or stored automatically, maybe in a third array c. And at the end, it could look like: c= [ a[2], a[6], a[18], a[7], a[0] .....]. Hope someone can help me with my problem. Thanks so much!
I'm not sure of the format of your arrays and what the objects contain. Using indexOf, https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf, may be a solution.
Using indexOf you can search the first array using the object that is clicked in the second array, you could then push this to a third array.
If I understand your problem correctly, your array a looks like this :
a = [{id:1} , {id:2} , {id:3} , {id:4}]
and then you randomly click on elements, so that they are then stored in an array b as such :
b = [{id:3}, {id:1}]
So eventually you want to memorize the information that a[2] is stored in position b[0], and a[0] is stored in position b[1], right?
What you could do is not store the entire objects in b, but just their id :
b = [3, 1]
This way, you can easily find what position they're at :
findPosition(node){
return b.indexOf( node.id )
}
console.log(findPosition(a[2])) // 0

Sort javascript object with array as value

I have a Javascript Object in the format key:pair where the pair is an array containing 2 timestamp values. I would like to sort this object so that the elements with the lowest numbers (earliest times) are displayed first.
Here is an example of the object: {"21_2":[1409158800,1409160000],"20_1":[1409148000,1409149200],"56_1":[1409149800,1409151600]}
So in this case, I would want the final sorted object to read:
{"20_1":[1409148000,1409149200],"56_1":[1409149800,1409151600],"21_2":[1409158800,1409160000]}
Obviously the sort() function will come into play here for the arrays, but how do I access those values inside the object? Note the object key isn't actually an integer because of the underscore.
I have found this: Sort Complex Array of Arrays by value within but haven't been able to apply it to my situation. Any help would be greatly appreciated.
You could change the structure of your data like this:
var myArray = [{
"id" : "21_2" // id or whatever these are
"timeStamps" : [1409158800,1409160000]
}, {
"id" : "20_1"
"timeStamps" : [1409148000,1409149200]
}];
Then you could sort it by the regular array sort:
myArray.sort(function(a, b){
// however you want to compare them:
return a.timeStamps[0] - b.timeStamps[0];
});

How does this snippet for removing duplicates from an array work

Regarding this post (Remove Duplicates from JavaScript Array) on creating a new array of unique values from another array.
Code in question:
uniqueArray = myArray.filter(function(elem, pos) {
return myArray.indexOf(elem) == pos;
})
Using this as the test data:
var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
Desired result is an array with only unique values:
var unique_names = ["Mike","Matt","Nancy","Adam","Jenny","Carl"];
Where I'm at:
I understand that filter will run a function on each member of the array, and that elem is the element being reviewed, and that pos is its index. If something causes that function to return false, then that element will not be included in the new array. So walking through it, this happens:
Is myArray.indexOf("Mike") the same as 0? Yes, so add "Mike" to the new array.
Is myArray.indexOf("Matt") the same as 1? Yes, so add "Matt" to the new array.
Is myArray.indexOf("Nancy") the same as 2? Yes, so add "Nancy" to the new array.
[repeat for all elements. All pass.]
Basically I don't get why the 2nd Nancy would evaluate to false.
The indexof is the index of the first appearance of the element, so the second Nancy would get the index of the first Nancy, and would be filtered out.
6) Is myArray.indexOf("Nancy") the same as 5? No (it's 2, just like it step 3), so skip the duplicated "Nancy".
indexOf gives you the first occurrence of the item.

Remove element from array, using slice

I am trying to remove a element from my array using slice, but i can't get it to work, look at this piece of code.
console.log(this.activeEffects); // Prints my array
console.log(this.activeEffects.slice(0,1)); // Remove from index 0, and remove one.
console.log(this.activeEffects); // Prints array again, this time my element should be gone
Result of this is.
So what is get from this is, at first the array is whole, as it should be. Then its prints what is sliced of the array. Finally the third should be empty? or?
function removeItemWithSlice(index) {
return [...items.slice(0, index), ...items.slice(index + 1)]
}
Slice will create a new array. We create two arrays: from beggining to index and from index+1 to end. Then we apply the spread operator (...) to take the items of those arrays and create a new single array containing all the items we care. I will paste an equivalent way if you don't like the one liner:
function removeItemWithSlice(index) {
const firstArr = items.slice(0, index);
const secondArr = items.slice(index + 1);
return [...firstArr , ...secondArr]
}
I believe you're looking for splice. From W3 Schools:
The splice() method adds/removes items to/from an array, and returns the removed item(s).
Take a look at the example on that page; the use case there is similar to what you want to achieve.
EDIT: Alternative link to MDN, as suggested by Nicosunshine; much more information about the command there.
a.slice(0, index).concat(a.slice(index + 1))
.slice does not mutate the array, you could use .splice() to remove the item at index i in the array:
this.activeEffects.splice(i, 1)
This is what I was able to come up with :
var newArray = oldArray.slice(indexOfElementToRemove+1).concat(oldArray.slice(0,indexOfElementToRemove));
Array.prototype.slice()...
does not alter the original array, but returns a new "one level
deep" copy that contains copies of the elements sliced from the
original array. Elements of the original array are copied into the new
array as follows:
Whereas Array.prototype.splice()...
Changes the content of an array, adding new elements while removing old elements.
This example should illustrate the difference.
// sample array
var list = ["a","b","c","d"];
// slice returns a new array
console.log("copied items: %o", list.slice(2));
// but leaves list itself unchanged
console.log("list: %o", list);
// splice modifies the array and returns a list of the removed items
console.log("removed items: %o", list.splice(2));
// list has changed
console.log("list: %o", list);
Look at here :
http://www.w3schools.com/jsref/jsref_slice_array.asp
You can see that the slice method select object et throw them into a new array object ^^ So you can't delete an object like this, may be you can try a thing like this :
var a = ["a","b","c"]; (pseudo code)
/* I wan't to remove the "b" object */
var result = a.slice(0,1)+a.slice(2,1); /* If you considers that "+" is a concatenation operator, i don't remember if it is true... */

Categories