How is possible to change 3/4 elements? Expected output is [1,2,4,3,5]
let list = [1,2,3,4,5];
const removeElement = list.indexOf(3); // remove number 3
list.slice(0, removeElement).concat(list.slice(removeElement+1)) // [1,2,4,5]
...next push number 3 after number 4 without splice
slice doesn't mutate the array on which it operates so you need to assign a value to what it returns
let list = [1,2,3,4,5];
const removeElement = list.indexOf(3); // remove number 3
var newList = list.slice(0, removeElement).concat(list.slice(removeElement+1)) // [1,2,4,5]
If you are prepared to use ES2015 syntax, you can use the spread operator as follows:
const removeElement = list.indexOf(3); // remove number 3
var es6List = [
...list.slice(0, removeElement),
...list.slice(removeElement+1)
];
console.log(es6List);
fiddle
The simplest way to write this is to use the spread operator:
let newList = [...list.slice(0, 2), list[3], list[2], ...list.slice(4)];
var list = [1,2,3,4,5];
var numToRemove = 3;
var removeElementIndex = list.indexOf(numToRemove);
var afterRemoveElement = list[removeElementIndex+1];
list.slice(0, removeElementIndex).concat(afterRemoveElement).concat(numToRemove).concat(list.slice(removeElementIndex+2)) // [1,2,4,3,5]
Object.assign actually works here
const newList = Object.assign([], list, {
2: list[3],
3: list[2],
});
list // [1,2,3,4,5]
newList // [1,2,4,3,5]
newList === list // false
The easer solution might be using filter instead of splice or slice. According to documentation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
It means the original array stays immutable. The only difference is that in this case, you have to know the value you want to delete instead of index.
let list = [1,2,3,4,5];
list.filter((item) => item !== 3);
Arrays are objects, use Object.assign() and access elements with property name expressions.
var numToMove = 2;
console.log(Object.assign(list, {[numToMove]: list[numToMove+1]},
{[numToMove+1]: list[numToMove]}));
// [1, 2, 4, 3, 5]
Related
I was trying to compare 2 different api calls from which i am able to make out 2 different arrays of ids , So i am trying to filter out the ids which already exist in array2 , and for the remaining ids i am trying to set the state , could anyone help me with it ?
code so far :
const [ prevAdmins , setPrevAdmins ] = useState<any>([]);
const [options, setOptions] = useState([{value: "", label: ""}]);
//API 1 CALL
get_user_groups({bot_id:params.botid , group_id:params.userid}).then((res) => {
setDetails(res?.data?.data[0]);
setGroupName(res?.data?.data[0].name)
let prevAdmins: any = [];
res?.data?.data[0]?.join_details.map((prevJoinee , idx) => {
prevAdmins.push(prevJoinee.user_id)
setPrevAdmins(prevAdmins)
})
});
//OUTPUT FOR API 1 "prevAdmins": ['61dfcfb71f492f4f4f589e93', '61dedd23bd15322626dd7539']
//2nd API CALL :
get_followers({bot_id:params.botid}).then((res) => {
if(res.data.data){
let option: any = [];
let allAdmins: any = [];
res.data.data.map((admin, index) => {
allAdmins.push(admin._id);
if(!prevAdmins.includes(allAdmins)){
option.push({value: admin._id, label: admin.displayName})
}
})
setOptions(option);
}
})
//OUTPUT FOR API 2 : ['61dfd02a1f492f4f4f589f00', '61dfcfb71f492f4f4f589e93', '61dedd23bd15322626dd7539']
Now what i am trying is to exclude the ids which is already present in Array 1 and setOptions should store the ids which are not excluded.
Regards !
If you want to get the unique values form your api calls, You can use Set instead of an array.
Please refer: https://www.javatpoint.com/typescript-set
You can use spread operator to combine two arrays and then convert it to Set and make an array from that Set. It will be unique.
roughly you can do something similar to this approach.
let array1 = [1,2,4]
let array2 = [4,3,5,6]
let combinedArray = [...array1, ...array2]
let arraySet = new Set(combinedArray)
let uniqueArray = Array.from(arraySet)
console.log(uniqueArray)
spread operator will combine two arrays but it will have duplicate values too.
when you convert it into Set, it will remove any duplicate values.
Then you can simply generate an array from that Set variable.
You can do this to make it short too.
let uniqueArray = Array.from(new Set([...array1, ...array2]))
after you have the unique array you can simply set state with the uniqueArray variable.
In your case:
if you are getting these two arrays.
let arr1 = ['61dfcfb71f492f4f4f589e93', '61dedd23bd15322626dd7539']
let arr2 =['61dfd02a1f492f4f4f589f00', '61dfcfb71f492f4f4f589e93', '61dedd23bd15322626dd7539']
you can do something like this
let uniqueArray = Array.from(new Set([...arr1, ...arr2]))
console.log(uniqueArray)
Given array:
const array = [{1: true},{2: false},{3: true},{}.....];
Filter the given array by only including objects with values of true.
Looking for the shortest solution.
const onlyTrue = array.filter((el, ind) => el[ind + 1] === true);
This will work only if indexes in array objects are ordered and starting from 1, as it is in your example.
Assumptions (based on what's in your example):
Each object in the array only has at least 1 property in it
The first property on each object is the one we care about
The property in each object is different every time
const array = [{1: true},{2: false},{3: true}];
const results = array.filter(item => Object.values(item)[0]);
If you want to avoid any false positives from truth-y values (see https://developer.mozilla.org/en-US/docs/Glossary/Truthy), then change the filter call to this instead:
const results = array.filter(item => Object.values(item)[0] === true);
const array = [{1: true},{2: false},{3: true}];
const array2 = [];
array.forEach(filterTrue);
function filterTrue(item){
for(x in item){
if(item[x]===true){
array2.push(item);
}
}
}
console.log(array2);
Hope this helps you.
Suppose I have an array var arr = [1,2,3] and if I do var result = arr.filter(callback) I want value of result would be [2,4,6] by the use of filter. I want to only define callback function in order to do so. It can be easily done with map but I want to use only filter.
Array.prototype.filter only filters existing values in an array, effectively creating a new array that can hold the same values, their subset, or an empty array, based on the filtering function.
You could do it using filter():
const arr = [1, 2, 3];
arr.filter((c, i) => {
arr[i] = +arr[i] * 2;
return true;
});
console.log(arr)
we are always returning true, so filter() makes no sense in this case.
As stated many times, there is no reason why you should do it.
It is impossible to do it like map because map returns a new array. You can either alter on the original array or you have to make a clone of the original array so you do not change it.
// this modifies the orginal array
var arr1 = [1,2,3]
arr1.filter((v,index,arr)=>{
arr[index] = v * 2;
return true
})
console.log(arr1)
// or you can clone it and do the same thing
// this modifies the cloned array
var arr2 = [1,2,3]
var arr3 = arr2.slice()
arr3.filter((v,index,arr)=>{
arr[index] = v * 2;
return true
})
console.log(arr2, arr3)
So no, you can not recreate map with filter since you HAVE to modify the original array or cheat and use a copy of the array.
So I'm not sure I understand the second part of your question, but as for the first part:
The callback for filter has three arguments, two of which are optional.
The first argument is the current element in the traversal, and the second and third arguments (the optional ones) are the 0-based index of the current element, and a reference to the original array.
This third parameter is useful for what you're trying to do.
let myArr = [1, 2, 3];
myArr.filter((el, ind, orig) => {
orig[ind] = orig[ind] + 1; // Or, whatever map logic you want to use
return true; // since a Boolean condition must be returned here
});
This way you can do it without even even having to break the scope of the function!
If you want to do it without necessarily having a variable to originally call filter on (you do have to pass an array), you can use the prototype and the call method:
Array.prototype.filter.call([1, 2, 3], (el, ind, orig) => {
orig[ind] = orig[ind] + 1;
return true;
});
I am curious to know how I can quickly and most efficiently remove a number of items from an array in JavaScript without creating a loop.
EXAMPLE:
var array = [1,2,3,4,5,6,7,8,9];
array.remove[0..4]; //pseudo code
console.log(array);//result would then be [6,7,8,9]
Is there a function for this, or is a custom loop required? Rudimentary question I suppose, but just wondering out of curiosity.
Use Array#splice:
var array = [1,2,3,4,5,6,7,8,9];
array.splice(0, 4); // returns [1,2,3,4]
console.log(array); // logs [5,6,7,8,9]
You could just use .slice() on the array.
var array = [1,2,3,4,5,6,7,8,9];
array = array.slice(5,array.length);
Using filter method
var a = [1,2,3,4,5,6,7,8,9], b = [];
b = a.filter(function(element, index){ return index > 4 });
Output of b[]
[6,7,8,9]
Set seems like a nice way to create Arrays with guaranteed unique elements, but it does not expose any good way to get properties, except for generator [Set].values, which is called in an awkward way of mySet.values.next().
This would have been ok, if you could call map and similar functions on Sets. But you cannot do that, as well.
I've tried Array.from, but seems to be converting only array-like (NodeList and TypedArrays ?) objects to Array. Another try: Object.keys does not work for Sets, and Set.prototype does not have similar static method.
So, the question: Is there any convenient inbuilt method for creating an Array with values of a given Set ? (Order of element does not really matter).
if no such option exists, then maybe there is a nice idiomatic one-liner for doing that ? like, using for...of, or similar ?
if no such option exists, then maybe there is a nice idiomatic
one-liner for doing that ? like, using for...of, or similar ?
Indeed, there are several ways to convert a Set to an Array:
Using Array.from:
Note: safer for TypeScript.
const array = Array.from(mySet);
Simply spreading the Set out in an array:
Note: Spreading a Set has issues when compiled with TypeScript (See issue #8856). It's safer to use Array.from above instead.
const array = [...mySet];
The old-fashioned way, iterating and pushing to a new array (Sets do have forEach):
const array = [];
mySet.forEach(v => array.push(v));
Previously, using the non-standard, and now deprecated array comprehension syntax:
const array = [v for (v of mySet)];
via https://speakerdeck.com/anguscroll/es6-uncensored by Angus Croll
It turns out, we can use spread operator:
var myArr = [...mySet];
Or, alternatively, use Array.from:
var myArr = Array.from(mySet);
Assuming you are just using Set temporarily to get unique values in an array and then converting back to an Array, try using this:
_.uniq([])
This relies on using underscore or lo-dash.
Perhaps to late to the party, but you could just do the following:
const set = new Set(['a', 'b']);
const values = set.values();
const array = Array.from(values);
This should work without problems in browsers that have support for ES6 or if you have a shim that correctly polyfills the above functionality.
Edit: Today you can just use what #c69 suggests:
const set = new Set(['a', 'b']);
const array = [...set]; // or Array.from(set)
Use spread Operator to get your desired result
var arrayFromSet = [...set];
The code below creates a set from an array and then, using the ... operator.
var arr=[1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,];
var set=new Set(arr);
let setarr=[...set];
console.log(setarr);
SIMPLEST ANSWER
just spread the set inside []
let mySet = new Set()
mySet.add(1)
mySet.add(5)
mySet.add(5)
let arr = [...mySet ]
Result: [1,5]
In my case the solution was:
var testSet = new Set();
var testArray = [];
testSet.add("1");
testSet.add("2");
testSet.add("2"); // duplicate item
testSet.add("3");
var someFunction = function (value1, value2, setItself) {
testArray.push(value1);
};
testSet.forEach(someFunction);
console.log("testArray: " + testArray);
value1 equals value2 => The value contained in the the current position in the Set. The same value is passed for both arguments
Worked under IE11.
Using Set and converting it to an array is very similar to copying an Array...
So you can use the same methods for copying an array which is very easy in ES6
For example, you can use ...
Imagine you have this Set below:
const a = new Set(["Alireza", "Dezfoolian", "is", "a", "developer"]);
You can simply convert it using:
const b = [...a];
and the result is:
["Alireza", "Dezfoolian", "is", "a", "developer"]
An array and now you can use all methods that you can use for an array...
Other common ways of doing it:
const b = Array.from(a);
or using loops like:
const b = [];
a.forEach(v => b.push(v));
the simplistic way to doing this
const array = [...new Set([1,1,2,3,3,4,5])]
console.log(array)
Here is an easy way to get only unique raw values from array. If you convert the array to Set and after this, do the conversion from Set to array. This conversion works only for raw values, for objects in the array it is not valid. Try it by yourself.
let myObj1 = {
name: "Dany",
age: 35,
address: "str. My street N5"
}
let myObj2 = {
name: "Dany",
age: 35,
address: "str. My street N5"
}
var myArray = [55, 44, 65, myObj1, 44, myObj2, 15, 25, 65, 30];
console.log(myArray);
var mySet = new Set(myArray);
console.log(mySet);
console.log(mySet.size === myArray.length);// !! The size differs because Set has only unique items
let uniqueArray = [...mySet];
console.log(uniqueArray);
// Here you will see your new array have only unique elements with raw
// values. The objects are not filtered as unique values by Set.
// Try it by yourself.
I would prefer to start with removing duplications from an array and then try to sort.
Return the 1st element from new array.
function processData(myArray) {
var s = new Set(myArray);
var arr = [...s];
return arr.sort((a,b) => b-a)[1];
}
console.log(processData([2,3,6,6,5]);
function countUniqueValues(arr) {
return Array.from(new Set(arr)).length
}
console.log(countUniqueValues([1, 2, 3, 4, 4, 4, 7, 7, 12, 12, 13]))