I am currently using lodash map to map over an array of objects.
I always need index 0 in the array to do something different.
Is there a way to make map start at index 1, without mutating or messing with the array?
I know that I can use slice(1). Just wondering if there was another way to start from index 1 rather than 0. So I didn't have to join them back together afterwards.
The second parameter of map accepts a function which has 3 arguments (value, index|key, collection).
So you can skip the first value using index and play with the rest of your data using value.
Something like this:
let data = [0, 1, 2];
let result = _.map(data, (value, index) => {
if (index === 0) {
return value;
} else {
return value * 2;
}
});
console.log(result);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.15/lodash.min.js"></script>
Related
Using React, I have data from an API response. I mapped the data and am storing the visitID, which would be the main identifier, into a variable. What I would like to do is look for any matching visitID values and store them into a new array, the issue I'm having is each instance is being stored in it's own array, for example:
['7065682'] at Index 0
['7065682'] at Index 1
['7065682'] at Index 2
['7047674'] at Index 3
['7047674'] at Index 4
I would like to look through each iteration and check all, put matching values into it's own array so I can write some logic based off each unique value. I just don't understand how to look through the next iteration. Here's my code, and the function 'duplicateVisitID' that I've been trying, but it doesn't give me the results I'm looking for.
{
Object.keys(this.state.EncounterData).length !== 0 ?
Object.values(this.state.EncounterData).map((encounter, i) => {
const visitID = [encounter.resource.identifier[1].value];
console.log(visitID, i);
const duplicateVisitID = function (visitID) {
if (visitID[i] === visitID[i])
return [visitID.concat(visitID[i])]
}
I am not sure what do you want to do, but if I understood right you want new array with only strings that are unique, not repeating. If yes see the code below. This is not the best performing one because of iteration inside iteration, but it will work for you. You can optimize it later by applying some algorithms.
The newArr is equal to ['7065682', '7047674']
const EncounteredData = [['7065682'], ['7065682'], ['7065682'], ['7047674'], ['7047674']];
const newArr = [];
for(let i of EncounteredData) {
for(let j of EncounteredData) {
if((i[0] !== j[0]) && !newArr.includes(i[0])) newArr.push(i[0]);
}
}
console.log(newArr);
If I understand correctly, you want an array of unique values? If so then you can use the map function and add any unique values to an array if the value is not already in it:
const uniqueVals = [];
EncounteredData.map((visitID) => {
if (!uniqueVals.includes(visitID[0])) {
uniqueVals.push(visitID[0]);
}
});
How can I make a search function using regEx?
I have some code but can't post it at the moment due to my computer being very broken and annoying, I will try again tomorrow!
This is not really what would be called combinations, but permutations.
The idea is to use recursion for getting the result for a shorter array, i.e. the one that lacks the first element.
Then take all permutations you get back from the recursive call, and insert the left-out value in each possible index.
When input has duplicates, then you need to stop inserting the left-out value as soon as you find that same value preceding the insertion spot.
Here is how that looks:
function scramble(array) {
if (array.length == 0) {
return [[]];
}
let results = [];
// solve the problem for a shorter array (first value excluded), and iterate:
for (let perm of scramble(array.slice(1))) {
// add the missing element in each possible position:
for (let i = 0; i < array.length; i++) {
// next IF is only needed when input has duplicates, and
// output should not repeat same array:
if (i && array[0] === perm[i-1]) break;
results.push(perm.slice(0, i).concat(array[0], perm.slice(i)));
}
}
return results;
}
let array = ["I", "am", "coding", "am"];
console.log(scramble(array));
Without the inner if, an input with duplicate values will produce duplicate arrays. If this is not desired, then the if is needed.
You could iterate and get a flat array of the mapping of the value with the result of the nested calls.
function permutation(array) {
return array.length === 1
? [array]
: array.flatMap((v, i) => permutation([
...array.slice(0, i),
...array.slice(i + 1)
]).map(a => [v, ...a]));
}
permutation(["I", "am", "coding"]).map(a => console.log(...a));
Lets say I have an array: [0,1,5].
The object I want to splice is object[0].content[1].content[5].splice()
However, the array can be however long, if it's just length 1,
then object[0].splice()
If it's length 2, object[0].content[1].splice()
I want to create a recursive function that does this, so I don't have to make a lot of if length conditionals. Any ideas on how to do this? Thank you
Recursion is neither necessary nor desirable for solving a problem of this type. All you need is a simple loop:
var array = [0, 1, 5];
var result = object[array.shift()];
while(var index = array.shift()) {
result = result.content[index];
}
var spliceResult = result.splice();
I get that recursiveness is not necessary in this situation. In the grand scheme neither is coding. But sometimes students like myself come to these places for help for specific questions based on constraints or edge cases. Try this one on for size. This specifically eliminates more than one occurrence of 0.
var takeOut = function(array) {
if (array.length === 0) { return array };
if(takeOut(array.slice(1))[0] === 0 && array[0] === 0) {
return takeOut(array.slice(1));
} else {
return [array[0]].concat(takeOut(array.slice(1)));
}
};
I am playing with reduce method provided by mozilla. Underscore provides its own version which seems very similar. Reducing an array is very simple.
ArrayName.reduce(function(a,b) {
return a +b;
});
I use a very similar approach when sorting arrays as well. However, what I do not understand is how to return a list of calls. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce Provides a really cool table that shows how their method works. I set my array pretty much the same
var array = [1,2,3,100,55,88,2];
var sortArray= function(a,b) {
return a -b;
}
var sorted = array.sort(sortArray);
var reduced = sorted.reduce(function(previousValue,currentValue, index,array){
return previousValue + currentValue;
});
What I wanted to set up though was each call that was made. I figured that I could simply reference the index in the return value with a , at the end.
return previousValue + currentValue, index;
However, that only returns the index. I am trying to figure a way to get the value of each call. Does this approach allow you to get each call?
You don't need to use reduce for what you are doing. Try
function running_total(array) {
var sum = 0;
return array.map(function(elt) {
return sum += elt;
};
}
Reduce is about "boiling down" an array to a "single thing". In contrast, map is about "transforming" elements of the array. Your problem (as I understand it) is to transform each element of the array into the sum of itself and all the preceding elements. Therefore, conceptually, it's a map, not a reduce.
Using the , in the return statement will only return index due to the comma operator rule
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
console.log(previousValue+"--"+currentValue)
return previousValue + currentValue;
});
this will do want you want
You can create another array and store its value for each progress.
var array = [1,2,3,100,55,88,2];
var sortArray= function(a,b) {
return a -b;
}
var sorted = array.sort(sortArray);
var progress = [];
var reduced = sorted.reduce(function(previousValue,currentValue, index,array){
progress[index] = previousValue + currentValue;
return progress[index];
}, 0);
// ^^^^^
// give it a init value so it starts at first element.
console.log(progress);
However, as torazaburo says, as you expect to get an array, you should use .map which returns an array instead of .reduce.
I have this code using lodash:
_.remove(this.home.modal.data.subTopics, function (currentObject) {
return currentObject.subTopicId === subTopicToDelete;
});
Can someone give me advice as to how I could do the same using modern browser functions without lodash?
Note it would be okay for the output of the remove to go into another variable.
You could use Array#filter() and negate the filter clause:
this.home.modal.data.subTopics.filter(function (currentObject) {
return currentObject.subTopicId !== subTopicToDelete;
});
This will return an array where subTopicId does not equal subTopicToDelete. It's then up to you to save it in a variable or wherever.
Or, if you want to create a method out of it, you could do:
function remove(array, filterMethod) {
return array.filter(function(){
return !filterMethod.apply(this, arguments);
});
}
Why not have a look at lodash's source code for _.remove?
function remove(array, predicate, thisArg) {
var index = -1,
length = array ? array.length : 0,
result = [];
predicate = getCallback(predicate, thisArg, 3);
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
result.push(value);
splice.call(array, index--, 1);
length--;
}
}
return result;
}
(The getCallback call is not really interesting here, just replace it with a predicate function that returns a boolean value for the given arguments: value, index, array. Not all of them need to be supplied obviously, this is JavaScript after all!)
Lodash uses Array.prototype.splice at the appropriate position, pushing the removed element onto the result array. Then it decreases the current loop index and the saved length by 1 using --, because every time you use .splice, you modify the array directly, for instance:
var arr = ['a', 'b'];
arr.splice(0, 1);
arr[1] // undefined
splice in this context really just the same as Array.prototype.splice. You can as well do array.splice(index--, 1).
A maybe more simple/understandable way is to (for-)loop through the array from the right, starting at array.length - 1 and ending at 0. Then splice every element at the current index, if it passes the predicate function, and push the result value of that operation onto the result array. Return the result array after the loop.
This works the same, because if you start removing elements from the right side, the index of the rest of the looped elements doesn't change. Maybe there are performance advantages to lo-dash's code, but I couldn't tell you that.
You could adapt Array.prototype to suit your needs. Some people don't like this approach, but it can be useful sometimes. In this example I pass in the key and the value I want to amend the array by:
if (!Array.prototype.remove) {
Array.prototype.remove = function (key, value) {
return this.filter(function (el) {
return el[key] !== value;
});
}
}
data.remove('name', 'dan');
DEMO