Add modifiers to duplicate elements in Lodash.js? - javascript

The input will be a list with duplicate elements like this:
['30','10','10','20','20','30']
And the output will be a list with modified elements like this:
['30#1', '10#1', '10#2', '20#1', '20#2', '30#2']
The # modifier indicates the time for this element to appear in the list..
Does anyone have ideas about this?

So you want the result to be an array with an item that corresponds to each item in the original array. That's a job for Array.prototype.map. You want to keep a running count of how many times each item has appeared, which you can do with a simple object. In every iteration you look up the number of times the item has appeared and add one. Store that number as the new count and use it to build your return value. Like this, more or less:
var arr = ['30', '10', '10', '20', '20', '30'];
var counts = {};
var arr2 = arr.map(function(item) {
counts[item] = (counts[item] || 0) + 1;
return item + "#" + counts[item];
});
You don't need Lodash for this at all.

Here's an example using lodash.
_.map(coll, function(item) {
return item + '#' +
_.set(this, item, _.get(this, item, 0) + 1)[item];
}, {});
What's nice is that you don't need to setup temporary variables here to compute your result. The idea is to store them in this - the empty object that's passed to map().
The get() function provides you with the 0 default if the property doesn't exist. So this can be used directly with set(), which sets the property value, and returns the object.

Example:
var count = {};
['30','10','10','20','20','30'].map(function(current) {
count[current] ? count[current] +=1 : count[current] = 1;
return current + '#' + count[current];
})

Related

How To Get Every Alternate Object In Array In JS

I wanted to know how can we get every alternate object in a array. For EG -
arr = ["foo","bar","foo1","bar1"]
I Need The values -
fir_alt = ["foo","foo1"]
sec_alt = ["bar","bar1"]
If This Helps This Is My Intention -
I am trying to link localstorage and firestore using the js-sdk.. Data is in array and have to take the array to store it back in localstorage.fir_alt would be the keys and sec_alt would be values. So I Can Make it Much More Multi-Device..
Thanks In Advance
You can use the filter function to filter out even and odd index's.
arr = ["foo","bar","foo1","bar1"]
fir_alt = arr.filter((element, index) => index % 2 == 0);
sec_alt = arr.filter((element, index) => index % 2 == 1);
console.log('fir_alt', fir_alt)
console.log('sec_alt', sec_alt)
I'd use an index variable and a loop(for/next or your fav). Examine the index on each iteration of the loop, and determine if the index is odd or even(or 0), then take the appropriate action to capture the desired values.
If I know what you mean... We can be reasoned with odd and even index.
In this way:
let arr = ["foo","bar","foo1", "bar1"],
fir_alt = [],
sec_alt = [];
for (let i=0;i<arr.length;i++){
if ((i+2)%2==0) {
sec_alt.push(arr[i]);
}
else {
fir_alt.push(arr[i]);
}
}

JavaScript Clearing Array Value

I have an array of arrays in JavaScript that I'm storing some values in, and I'm attempting to find a way to clear the value within that array when the user removes the specified control from the page, however I'm not finding a good way to do this and anything I try doesn't seem to be working.
What is the best method for clearing the value in the array? I'd prefer the value to be null so that it's skipped when I iterate over the array later on.
I've tried to do MyArray[id][subid] = '' but that still is technically a value. I've also tried to do MyArray[id][subid].length = 0 but that doesn't seem to do anything either. Trying to grab the index and splice it from the array returns a -1 and therefore doesn't work either.
var MyArray;
window.onload = function(){
MyArray = new Array();
}
function EditValuesAdd(){
var Input = document.getElementById('Values-Input').value;
var ID = document.getElementById('FID').value;
var ValueID = ControlID(); // generate GUID
if (!MyArray[ID]) MyArray[ID] = new Array();
MyArray[ID][ValueID] = Input;
document.getElementById('Values').innerHTML += '<a href="#" id="FV-' + ValueID + '" onclick="EditValuesRemove(this.id)"/><br id="V-' + ValueID + '"/>';
}
function EditValuesRemove(id)
{
var ID = document.getElementById('FID').value;
document.getElementById(id).remove();
document.getElementById(id.replace('FV-', 'V-')).remove();
MyArray[ID][id.replace('FV-', '')] = '';
}
I've also tried to do an index of and then splice it from the underlying array but the index always returns -1.
var Index = MyArray[ID].indexOf(id.replace('FV-', ''));
MyArray[ID].splice(Index, 1);
Setting the length to zero has no effect either.
MyArray[ID][id.replace('FV-', '')].length = 0;
I would expect that one of the methods above would clear out the value and make it null so that it is skipped later on but all of the methods I've found and tried so far leave some non-null value.
What you need is an object (a Map), not an array (a list).
Here's a basic idea of how to do it :
MyArray = {};
....
if (!MyArray[ID]) MyArray[ID] = {}
MyArray[ID][ValueID] = Input;
...
delete MyArray[ID][id.replace('FV-', '')];
Check here for more information : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
In the end I used an array of objects MyArray = [] and then using splice/findindex to remove it from the array:
function RemoveItem(id)
{
var Index = MyArray.findIndex(a => a.ID == id.replace('FV-', ''));
MyArray.splice(Index, 1);
document.getElementById(id).remove();
document.getElementById('FVB-' + id.replace('FV-', '')).remove();
}
It doesn't solve the actual question asked but I don't know if there really is an answer since I was using arrays in the wrong manner. Hopefully this at least points someone else in the right direction when dealing with arrays and objects.

Accessing the previous element in $('.class').each()

Is there a way to access the previous or next element while in a certain iteration of a $('.class').each() loop; Where the elements with class 'class' are not siblings?
I was able to do this by traversing through the DOM tree. But I was wondering if there is a more concrete and elegant solution.
Current code:
$('.slider-range').each(function(index){
var temp = $(this).closest('.panel').next('.panel').find('.slider-range');
//do something with temp
});
You will have to "store" the "selected" items in a variable and use the index passed to the callback like this:
var range = $('.slider-range');
range.each(function(index){
var temp = index > 0 ? range[index - 1] : null;
//do something with temp
});
I added a condition on the value of the index, to make the tempvariable null if index is 0.
Edit: Corrected with index - 1 to "select" the previous item.
In your loop, you have access to the current index within the collection of jquery objects.
$('.slider-range').each(function(index){
var temp = $(this).closest('.panel').next('.panel').find('.slider-range');
//do something with temp
});
You can use this to get any of the other items in that collection:
var items = $(".slider-range");
items.each(function(index) {
if (index > 0) {
var prev = items[index-1];
// do something with prev
}
});

JavaScript find index of value in a column of an array (read from csv with papaparse)

Very close but slightly more complex than this question I have an array and I want to obtain the index of the array of the first occurrence of a value of a given object of this array.
My array has several objects of integer and text, and has an id object of integers (which I call with this instruction wup[i].id).
[edit] The array comes from reading a csv file with header with papaparse.
wup = ["id", "cityName", etc ... ]
[20002, "Tokyo", etc ... ]
[20003, "GoiĆ¢nia", etc ... ]
It is in this id object only that I want to find the input value and finally get the index of this input value. This is certainly using indexOf but how to focus the search only in the id object?
[edit] the instruction that fails is the following (try to find the occurrence of tn[iter].idOri in the array wup, that I expect to retrieve in the variable iOri):
var iOri = wup.indexOf(tn[iter].idOri);
Hoping it is clear enough.
There are lots of ways to do this, map your array down to a flat array of ids:
var myId = 3;
var ids = array.map(function(obj) {
return obj.id;
});
var index = ids.indexOf(myId);
A more succinct (and better - because it only requires one iteration) method would be to use Array.findIndex:
var myId = 3;
var index = array.findIndex(function(obj) {
return obj.id === myId;
});
With es6:
var myId = 3;
var index = array.map(obj => obj.id).indexOf(myId);
or
var myId = 3;
var index = array.findIndex(obj => obj.id === myId);

Remove item from array in JavaScript

Seen this question a lot, but cannot find something that's what i'm looking for.
onClick I push an item to an array I have, however, if there's 3 items in my array I don't want to be able to push items anymore.
var selectedData = [];
I set my empty variable.
var index = selectedData.indexOf(3);
I then get the index of my array which is 3
if (index > 3) {
selectedData.splice(index, 1);
}
Then within my if statement I say, if my index which is 3, is bigger then 3, then splice at index and remove one.
selectedData.push(TheThing);
I then push TheThing to my array if the if statement above isn't true.
However, I have a variable var arrayLength = selectedData.length; that grabs the length, and when I console log it, it starts at 0 and splices items anything after 4. Not 3.
Any idea what i've done wrong or misunderstood?
Thanks
More full example of my code
var selectedData = [];
myElement.on('click', function() {
var index = selectedData.indexOf(3);
if (index > 3) {
selectedData.splice(index, 1);
}
var arrayLength = selectedData.length;
console.log(arrayLength, 'the length');
});
So in short, onClick check my array and remove anything after the third that gets added into my array.
Do you want this to behave as a stack or a queue?
So your code here:
var index = selectedData.indexOf(3);
Is not grabbing the 3rd index - its grabbing the first index where it sees 3, or -1 if it doesn't. Replace your if statement with,
if (selectedData.length > 3) {
selectedData.pop() // removes last element (stack)
// or
selectedData = selectedData.slice(1) //remove first element (queue)
}
I think you need to try var arrayLength = selectedData.length -1;
You start at 0 like a normal array, but don't you start with an empty array?
Plus when you use .length, it returns the true count of the array or collection not a 0 index.
`
you can override push() method of your array like this:
var a = [];
a.push = function(){}
or like this
a.push = function (newEl){
if(this.length <3){
Array.prototype.push.call(this, newEl)
}
}
This is not complete example because push() can take many arguments and you should to handle this case too
var index = selectedData.indexOf(3); simply give you the index of the element of the array that has value 3
Example
selectedData = [ 0, 3 , 2];
alert( selectedData.indexOf( 3 ) ); // this will alert "1" that is the index of the element with value "3"
you can use this scenario
var selectedData = [];
myElement.on('click', function() {
//if selectedData length is less than 3, push items
});
This could work.
myElement.on('click', function() {
if(selectedData.length > 3){
selectedData = selectedData.splice(0, 3);
}
console.log(selectedData.length, 'the length');
});

Categories