How to replace item in array? - javascript

Each item of this array is some number:
var items = Array(523,3452,334,31, ...5346);
How to replace some item with a new one?
For example, we want to replace 3452 with 1010, how would we do this?

var index = items.indexOf(3452);
if (index !== -1) {
items[index] = 1010;
}
Also it is recommend you not use the constructor method to initialize your arrays. Instead, use the literal syntax:
var items = [523, 3452, 334, 31, 5346];
You can also use the ~ operator if you are into terse JavaScript and want to shorten the -1 comparison:
var index = items.indexOf(3452);
if (~index) {
items[index] = 1010;
}
Sometimes I even like to write a contains function to abstract this check and make it easier to understand what's going on. What's awesome is this works on arrays and strings both:
var contains = function (haystack, needle) {
return !!~haystack.indexOf(needle);
};
// can be used like so now:
if (contains(items, 3452)) {
// do something else...
}
Starting with ES6/ES2015 for strings, and proposed for ES2016 for arrays, you can more easily determine if a source contains another value:
if (haystack.includes(needle)) {
// do your thing
}

The Array.indexOf() method will replace the first instance. To get every instance use Array.map():
a = a.map(function(item) { return item == 3452 ? 1010 : item; });
Of course, that creates a new array. If you want to do it in place, use Array.forEach():
a.forEach(function(item, i) { if (item == 3452) a[i] = 1010; });

Answer from #gilly3 is great.
Replace object in an array, keeping the array order unchanged
I prefer the following way to update the new updated record into my array of records when I get data from the server. It keeps the order intact and quite straight forward one liner.
users = users.map(u => u.id !== editedUser.id ? u : editedUser);
var users = [
{id: 1, firstname: 'John', lastname: 'Ken'},
{id: 2, firstname: 'Robin', lastname: 'Hood'},
{id: 3, firstname: 'William', lastname: 'Cook'}
];
var editedUser = {id: 2, firstname: 'Michael', lastname: 'Angelo'};
users = users.map(u => u.id !== editedUser.id ? u : editedUser);
console.log('users -> ', users);

My suggested solution would be:
items.splice(1, 1, 1010);
The splice operation will start at index 1, remove 1 item in the array (i.e. 3452), and will replace it with the new item 1010.

Use indexOf to find an element.
var i = items.indexOf(3452);
items[i] = 1010;

First method
Best way in just one line to replace or update item of array
array.splice(array.indexOf(valueToReplace), 1, newValue)
Eg:
let items = ['JS', 'PHP', 'RUBY'];
let replacedItem = items.splice(items.indexOf('RUBY'), 1, 'PYTHON')
console.log(replacedItem) //['RUBY']
console.log(items) //['JS', 'PHP', 'PYTHON']
Second method
An other simple way to do the same operation is :
items[items.indexOf(oldValue)] = newValue

Easily accomplished with a for loop.
for (var i = 0; i < items.length; i++)
if (items[i] == 3452)
items[i] = 1010;

If using a complex object (or even a simple one) and you can use es6, Array.prototype.findIndex is a good one. For the OP's array, they could do,
const index = items.findIndex(x => x === 3452)
items[index] = 1010
For more complex objects, this really shines. For example,
const index =
items.findIndex(
x => x.jerseyNumber === 9 && x.school === 'Ohio State'
)
items[index].lastName = 'Utah'
items[index].firstName = 'Johnny'

You can edit any number of the list using indexes
for example :
items[0] = 5;
items[5] = 100;

ES6 way:
const items = Array(523, 3452, 334, 31, ...5346);
We wanna replace 3452 with 1010, solution:
const newItems = items.map(item => item === 3452 ? 1010 : item);
Surely, the question is for many years ago and for now I just prefer to use immutable solution, definitely, it is awesome for ReactJS.
For frequent usage I offer below function:
const itemReplacer = (array, oldItem, newItem) =>
array.map(item => item === oldItem ? newItem : item);

A functional approach to replacing an element of an array in javascript:
const replace = (array, index, ...items) => [...array.slice(0, index), ...items, ...array.slice(index + 1)];

The immutable way to replace the element in the list using ES6 spread operators and .slice method.
const arr = ['fir', 'next', 'third'], item = 'next'
const nextArr = [
...arr.slice(0, arr.indexOf(item)),
'second',
...arr.slice(arr.indexOf(item) + 1)
]
Verify that works
console.log(arr) // [ 'fir', 'next', 'third' ]
console.log(nextArr) // ['fir', 'second', 'third']

Replacement can be done in one line:
var items = Array(523, 3452, 334, 31, 5346);
items[items.map((e, i) => [i, e]).filter(e => e[1] == 3452)[0][0]] = 1010
console.log(items);
Or create a function to reuse:
Array.prototype.replace = function(t, v) {
if (this.indexOf(t)!= -1)
this[this.map((e, i) => [i, e]).filter(e => e[1] == t)[0][0]] = v;
};
//Check
var items = Array(523, 3452, 334, 31, 5346);
items.replace(3452, 1010);
console.log(items);

var items = Array(523,3452,334,31,5346);
If you know the value then use,
items[items.indexOf(334)] = 1010;
If you want to know that value is present or not, then use,
var point = items.indexOf(334);
if (point !== -1) {
items[point] = 1010;
}
If you know the place (position) then directly use,
items[--position] = 1010;
If you want replace few elements, and you know only starting position only means,
items.splice(2, 1, 1010, 1220);
for more about .splice

The easiest way is to use some libraries like underscorejs and map method.
var items = Array(523,3452,334,31,...5346);
_.map(items, function(num) {
return (num == 3452) ? 1010 : num;
});
=> [523, 1010, 334, 31, ...5346]

If you want a simple sugar sintax oneliner you can just:
(elements = elements.filter(element => element.id !== updatedElement.id)).push(updatedElement);
Like:
let elements = [ { id: 1, name: 'element one' }, { id: 2, name: 'element two'} ];
const updatedElement = { id: 1, name: 'updated element one' };
If you don't have id you could stringify the element like:
(elements = elements.filter(element => JSON.stringify(element) !== JSON.stringify(updatedElement))).push(updatedElement);

var index = Array.indexOf(Array value);
if (index > -1) {
Array.splice(index, 1);
}
from here you can delete a particular value from array and based on the same index
you can insert value in array .
Array.splice(index, 0, Array value);

Well if anyone is interresting on how to replace an object from its index in an array, here's a solution.
Find the index of the object by its id:
const index = items.map(item => item.id).indexOf(objectId)
Replace the object using Object.assign() method:
Object.assign(items[index], newValue)

items[items.indexOf(3452)] = 1010
great for simple swaps. try the snippet below
const items = Array(523, 3452, 334, 31, 5346);
console.log(items)
items[items.indexOf(3452)] = 1010
console.log(items)

Here is the basic answer made into a reusable function:
function arrayFindReplace(array, findValue, replaceValue){
while(array.indexOf(findValue) !== -1){
let index = array.indexOf(findValue);
array[index] = replaceValue;
}
}

Here's a one liner. It assumes the item will be in the array.
var items = [523, 3452, 334, 31, 5346]
var replace = (arr, oldVal, newVal) => (arr[arr.indexOf(oldVal)] = newVal, arr)
console.log(replace(items, 3452, 1010))

const items = Array(1, 2, 3, 4, 5);
console.log(items)
items[items.indexOf(2)] = 1010
console.log(items)

First, rewrite your array like this:
var items = [523,3452,334,31,...5346];
Next, access the element in the array through its index number. The formula to determine the index number is: n-1
To replace the first item (n=1) in the array, write:
items[0] = Enter Your New Number;
In your example, the number 3452 is in the second position (n=2). So the formula to determine the index number is 2-1 = 1. So write the following code to replace 3452 with 1010:
items[1] = 1010;

I solved this problem using for loops and iterating through the original array and adding the positions of the matching arreas to another array and then looping through that array and changing it in the original array then return it, I used and arrow function but a regular function would work too.
var replace = (arr, replaceThis, WithThis) => {
if (!Array.isArray(arr)) throw new RangeError("Error");
var itemSpots = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] == replaceThis) itemSpots.push(i);
}
for (var i = 0; i < itemSpots.length; i++) {
arr[itemSpots[i]] = WithThis;
}
return arr;
};

presentPrompt(id,productqty) {
let alert = this.forgotCtrl.create({
title: 'Test',
inputs: [
{
name: 'pickqty',
placeholder: 'pick quantity'
},
{
name: 'state',
value: 'verified',
disabled:true,
placeholder: 'state',
}
],
buttons: [
{
text: 'Ok',
role: 'cancel',
handler: data => {
console.log('dataaaaname',data.pickqty);
console.log('dataaaapwd',data.state);
for (var i = 0; i < this.cottonLists.length; i++){
if (this.cottonLists[i].id == id){
this.cottonLists[i].real_stock = data.pickqty;
}
}
for (var i = 0; i < this.cottonLists.length; i++){
if (this.cottonLists[i].id == id){
this.cottonLists[i].state = 'verified';
}
}
//Log object to console again.
console.log("After update: ", this.cottonLists)
console.log('Ok clicked');
}
},
]
});
alert.present();
}
As per your requirement you can change fields and array names.
thats all. Enjoy your coding.

The easiest way is this.
var items = Array(523,3452,334,31, 5346);
var replaceWhat = 3452, replaceWith = 1010;
if ( ( i = items.indexOf(replaceWhat) ) >=0 ) items.splice(i, 1, replaceWith);
console.log(items);
>>> (5) [523, 1010, 334, 31, 5346]

When your array have many old item to replace new item, you can use this way:
function replaceArray(array, oldItem, newItem) {
for (let i = 0; i < array.length; i++) {
const index = array.indexOf(oldItem);
if (~index) {
array[index] = newItem;
}
}
return array
}
console.log(replaceArray([1, 2, 3, 2, 2, 8, 1, 9], 2, 5));
console.log(replaceArray([1, 2, 3, 2, 2, 8, 1, 9], 2, "Hi"));

let items = Array(523,3452,334,31, 5346);
items[0]=1010;

This will do the job
Array.prototype.replace = function(a, b) {
return this.map(item => item == a ? b : item)
}
Usage:
let items = ['hi', 'hi', 'hello', 'hi', 'hello', 'hello', 'hi']
console.log(items.replace('hello', 'hi'))
Output:
['hi', 'hi', 'hi', 'hi', 'hi', 'hi', 'hi']
The nice thing is, that EVERY array will have .replace() property.

Related

write a function that takes two parameters - an array and a number [duplicate]

Say I've got this
imageList = [100,200,300,400,500];
Which gives me
[0]100 [1]200 etc.
Is there any way in JavaScript to return the index with the value?
I.e. I want the index for 200, I get returned 1.
You can use indexOf:
var imageList = [100,200,300,400,500];
var index = imageList.indexOf(200); // 1
You will get -1 if it cannot find a value in the array.
For objects array use map with indexOf:
var imageList = [
{value: 100},
{value: 200},
{value: 300},
{value: 400},
{value: 500}
];
var index = imageList.map(function (img) { return img.value; }).indexOf(200);
console.log(index);
In modern browsers you can use findIndex:
var imageList = [
{value: 100},
{value: 200},
{value: 300},
{value: 400},
{value: 500}
];
var index = imageList.findIndex(img => img.value === 200);
console.log(index);
Its part of ES6 and supported by Chrome, FF, Safari and Edge
Use jQuery's function
jQuery.inArray
jQuery.inArray( value, array [, fromIndex ] )
(or) $.inArray( value, array [, fromIndex ] )
Here is an another way find value index in complex array in javascript. Hope help somebody indeed.
Let us assume we have a JavaScript array as following,
var studentsArray =
[
{
"rollnumber": 1,
"name": "dj",
"subject": "physics"
},
{
"rollnumber": 2,
"name": "tanmay",
"subject": "biology"
},
{
"rollnumber": 3,
"name": "amit",
"subject": "chemistry"
},
];
Now if we have a requirement to select a particular object in the array. Let us assume that we want to find index of student with name Tanmay.
We can do that by iterating through the array and comparing value at the given key.
function functiontofindIndexByKeyValue(arraytosearch, key, valuetosearch) {
for (var i = 0; i < arraytosearch.length; i++) {
if (arraytosearch[i][key] == valuetosearch) {
return i;
}
}
return null;
}
You can use the function to find index of a particular element as below,
var index = functiontofindIndexByKeyValue(studentsArray, "name", "tanmay");
alert(index);
Use indexOf
imageList.indexOf(200)
how about indexOf ?
alert(imageList.indexOf(200));
Array.indexOf doesnt work in some versions of internet explorer - there are lots of alternative ways of doing it though ... see this question / answer : How do I check if an array includes an object in JavaScript?
When the lists aren't extremely long, this is the best way I know:
function getIndex(val) {
for (var i = 0; i < imageList.length; i++) {
if (imageList[i] === val) {
return i;
}
}
}
var imageList = [100, 200, 300, 400, 500];
var index = getIndex(200);
It is possible to use a ES6 function Array.prototype.findIndex.
MDN says:
The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise -1 is returned.
var fooArray = [5, 10, 15, 20, 25];
console.log(fooArray.findIndex(num=> { return num > 5; }));
// expected output: 1
Find an index by object property.
To find an index by object property:
yourArray.findIndex(obj => obj['propertyName'] === yourValue)
For example, there is a such array:
let someArray = [
{ property: 'OutDate' },
{ property: 'BeginDate'},
{ property: 'CarNumber' },
{ property: 'FirstName'}
];
Then, code to find an index of necessary property looks like that:
let carIndex = someArray.findIndex( filterCarObj=>
filterCarObj['property'] === 'CarNumber');
In a multidimensional array.
Reference array:
var array = [
{ ID: '100' },
{ ID: '200' },
{ ID: '300' },
{ ID: '400' },
{ ID: '500' }
];
Using filter and indexOf:
var index = array.indexOf(array.filter(function(item) { return item.ID == '200' })[0]);
Looping through each item in the array using indexOf:
for (var i = 0; i < array.length; i++) {
var item = array[i];
if (item.ID == '200') {
var index = array.indexOf(item);
}
}
Here is my take on it, seems like most peoples solutions don't check if the item exists and it removes random values if it does not exist.
First check if the element exists by looking for it's index.
If it does exist, remove it by its index using the splice method
elementPosition = array.indexOf(value);
if(elementPosition != -1) {
array.splice(elementPosition, 1);
}
// Instead Of
var index = arr.indexOf(200)
// Use
var index = arr.includes(200);
Please Note: Includes function is a simple instance method on the array and helps to easily find if an item is in the array(including NaN unlike indexOf)

How to check if particular element in an array has duplicate?

There is a lot of examples that illustrate how to find duplicates in an array, but I can't find the simple one that checks if particular element has duplicate. Therefore, the array of strings is input and the output is Boolean that tells us if particular element has duplicate or not.
For example:
array = ['name1', 'name2', 'name3', 'name2']
I need a function that returns "false" if element in an array is not unique, and "true" if it is.
Here is a sample code , with which you can identify whether a particular element is duplicated in an array or not
const beasts = ["ant", "bison", "camel", "duck", "bison"];
const searchKey = "ant";
let index = beasts.indexOf(searchKey);
let isDuplicate = false;
if (index == -1) {
console.log("Element not present in array");
} else {
index = beasts.indexOf(searchKey, index + 1);
if (index > -1) {
isDuplicate = true;
}
}
console.log(isDuplicate);
## Solution 2
Convert array to set.
Set removes all duplicate records
array = ["name1", "name2", "name3", "name2"];
let set = new Set(array);
if (array.lenght === set.size) {
console.log("Unique array items");
} else {
console.log("Not unique array");
}
You can modify the code as per your needs.
const isUnique = (arr, x) => arr.filter(v => v === x).length <= 1
const x = [1, 2, 3, 1, 2, 3, 4, 5]
console.log(isUnique(x, 3), isUnique(x, 5))
How do you think about this?
function isUnique(arr) {
const hash = {}
for(const item of arr) {
hash[item] = (hash[item] || 0) + 1
if(hash[item] > 1) {
return false
}
}
return true
}
console.log(isUnique(['item1', 'item2', 'item1']))
console.log(isUnique(['item1', 'item2', 'item3']))
Try this. I hope this the solution you are trying to solve.
array1 = ['name1', 'name2', 'name3', 'name2'];
array2 = ['name1', 'name2', 'name3', 'name4'];
console.log(isUnique(array1));
console.log(isUnique(array2));
function isUnique(array) {
var valuesSoFar = [];
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (valuesSoFar.indexOf(value) !== -1) {
return false;
}
valuesSoFar.push(value);
}
return true;
}

Replace array entry with spread syntax in one line of code? [duplicate]

This question already has answers here:
Replace element at specific position in an array without mutating it
(9 answers)
Closed 3 months ago.
I'm replacing an item in a react state array by using the ... spread syntax. This works:
let newImages = [...this.state.images]
newImages[4] = updatedImage
this.setState({images:newImages})
Would it be possible to do this in one line of code? Something like this? (this doesn't work obviously...)
this.setState({images: [...this.state.images, [4]:updatedImage})
use Array.slice
this.setState({
images: [
...this.state.images.slice(0, 4),
updatedImage,
...this.state.images.slice(5),
],
});
Edit from original post: changed the 3 o a 4 in the second parameter of the slice method since the second parameter points to the member of the array that is beyond the last one kept, it now correctly answers the original question.
Once the change array by copy proposal is widely supported (it's at Stage 3, so should be finding its way into JavaScript engines), you'll be able to do this with the new with method:
// Using a Stage 3 proposal, not widely supported yet as of Nov 17 2022
this.setState({images: this.state.images.with(4, updatedImage)});
Until then, Object.assign does the job:
this.setState({images: Object.assign([], this.state.images, {4: updatedImage}));
...but involves a temporary object (the one at the end). Still, just the one temp object... If you do this with slice and spreading out arrays, it involve several more temporary objects (the two arrays from slice, the iterators for them, the result objects created by calling the iterator's next function [inside the ... handle], etc.).
It works because normal JS arrays aren't really arrays1 (this is subject to optimization, of course), they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2. So there, we're spreading out this.state.images into a new array, passing that into Object.assign as the target, and giving Object.assign an object with a property named "4" (yes, it ends up being a string but we're allowed to write it as a number) with the value we want to update.
Live Example:
const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([], a, {4: "four"});
console.log(b);
If the 4 can be variable, that's fine, you can use a computed property name (new in ES2015):
let n = 4;
this.setState({images: Object.assign([], this.state.images, {[n]: updatedImage}));
Note the [] around n.
Live Example:
const a = [0, 1, 2, 3, 4, 5, 6, 7];
const index = 4;
const b = Object.assign([], a, {[index]: "four"});
console.log(b);
1 Disclosure: That's a post on my anemic little blog.
2 It's the second paragraph after the bullet list:
An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.
So that Object.assign does the same thing as your create-the-array-then-update-index-4.
You can use map:
const newImages = this.state.images
.map((image, index) => index === 4 ? updatedImage : image)
You can convert the array to objects (the ...array1), replace the item (the [1]:"seven"), then convert it back to an array (Object.values) :
array1 = ["one", "two", "three"];
array2 = Object.values({...array1, [1]:"seven"});
console.log(array1);
console.log(array2);
Here is my self explaning non-one-liner
const wantedIndex = 4;
const oldArray = state.posts; // example
const updated = {
...oldArray[wantedIndex],
read: !oldArray[wantedIndex].read // attributes to change...
}
const before = oldArray.slice(0, wantedIndex);
const after = oldArray.slice(wantedIndex + 1);
const menu = [
...before,
updated,
...after
]
I refer to #Bardia Rastin solution, and I found that the solution has a mistake at the index value (it replaces item at index 3 but not 4).
If you want to replace the item which has index value, index, the answer should be
this.setState({images: [...this.state.images.slice(0, index), updatedImage, ...this.state.images.slice(index + 1)]})
this.state.images.slice(0, index) is a new array has items start from 0 to index - 1 (index is not included)
this.state.images.slice(index) is a new array has items starts from index and afterwards.
To correctly replace item at index 4, answer should be:
this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
first find the index, here I use the image document id docId as illustration:
const index = images.findIndex((prevPhoto)=>prevPhoto.docId === docId)
this.setState({images: [...this.state.images.slice(0,index), updatedImage, ...this.state.images.slice(index+1)]})
I have tried a lot of using the spread operator. I think when you use splice() it changes the main array. So the solution I discovered is to clone the array in new variables and then split it using the spread operator. The example I used.
var cart = [];
function addItem(item) {
let name = item.name;
let price = item.price;
let count = item.count;
let id = item.id;
cart.push({
id,
name,
price,
count,
});
return;
}
function removeItem(id) {
let itemExist = false;
let index = 0;
for (let j = 0; j < cart.length; j++) {
if (cart[j].id === id) { itemExist = true; break; }
index++;
}
if (itemExist) {
cart.splice(index, 1);
}
return;
}
function changeCount(id, newCount) {
let itemExist = false;
let index = 0;
for (let j = 0; j < cart.length; j++) {
console.log("J: ", j)
if (cart[j].id === id) {
itemExist = true;
index = j;
break;
}
}
console.log(index);
if (itemExist) {
let temp1 = [...cart];
let temp2 = [...cart];
let temp3 = [...cart];
cart = [...temp1.splice(0, index),
{
...temp2[index],
count: newCount
},
...temp3.splice(index + 1, cart.length)
];
}
return;
}
addItem({
id: 1,
name: "item 1",
price: 10,
count: 1
});
addItem({
id: 2,
name: "item 2",
price: 11,
count: 1
});
addItem({
id: 3,
name: "item 3",
price: 12,
count: 2
});
addItem({
id: 4,
name: "item 4",
price: 13,
count: 2
});
changeCount(4, 5);
console.log("AFTER CHANGE!");
console.log(cart);

How to stop duplicate values in a loop?

I am using this code to read all the values from each object with the key "category":
const listChapter = datas.map((data) => console.log(data.category))
datas is an array of Objects, and there are 45 objects.
The problem is that when I console.log that, i have many duplicates values, you can see that below:
console.log results
I want to have one unique value of each category. How can I do that?
Filter duplicates from the data before you iterate through them.
var unique = datas.reduce(function(unique, data) {
return unique.indexOf(data.category) === -1 ? unique.concat(data.category) : unique;
}, []);
You also can do the trick with the Set:
let data = ['Alfa', 'Alfa', 'Beta', 'Gamma', 'Beta', 'Omega', 'Psi', 'Beta', 'Omega'];
let arr = [... new Set(data)];
// Or = Array.from(new Set(data));
console.log(arr);
Edit: I forgot that you have array of objects. In that case:
let data2 = [
{'category': 'Alfa'},
{'category': 'Alfa'},
{'category': 'Beta'}
]
let set = new Set();
data2.forEach((data) => {
set.add(data.category);
});
let arr2 = [... set];
console.log(arr2);
This is minor improvement of Tomek's answer. (I am not able comment yet.)
const arr = [
{'category': 'Alfa'},
{'category': 'Alfa'},
{'category': 'Beta'}
];
const unique = [...new Set(arr.map(item => item.category))];
This approach is faster, because of less iterations:
const listChapter = Object.keys(datas.reduce((ac, el) => {
ac[el.category] = true
return ac
}, {}))
arr is the whole array.
for(var i = 0; i < data.length; i++) {
if(arr[i] == data.category) {
remove item here;
}
}
Here's an alternative one-liner using filter() (just for fun):
console.log(datas.filter((data, i, a) =>
i === a.findIndex(data2 => data.category === data2.category)));

JavaScript move an item of an array to the front

I want to check if an array contains "role". If it does, I want to move the "role" to the front of the array.
var data= ["email","role","type","name"];
if ("role" in data) data.remove(data.indexOf("role")); data.unshift("role")
data;
Here, I got the result:
["role", "email", "role", "type", "name"]
How can I fix this?
You can sort the array and specify that the value "role" comes before all other values, and that all other values are equal:
var first = "role";
data.sort(function(x,y){ return x == first ? -1 : y == first ? 1 : 0; });
Demo: http://jsfiddle.net/Guffa/7ST24/
The cleanest solution in ES6 in my opinion:
let data = ["email","role","type","name"];
data = data.filter(item => item !== "role");
data.unshift("role");
let data = [0, 1, 2, 3, 4, 5];
let index = 3;
data.unshift(data.splice(index, 1)[0]);
// data = [3, 0, 1, 2, 4, 5]
My first thought would be:
var data= ["email","role","type","name"];
// if it's not there, or is already the first element (of index 0)
// then there's no point going further:
if (data.indexOf('role') > 0) {
// find the current index of 'role':
var index = data.indexOf('role');
// using splice to remove elements from the array, starting at
// the identified index, and affecting 1 element(s):
data.splice(index,1);
// putting the 'role' string back in the array:
data.unshift('role');
}
console.log(data);
To revise, and tidy up a little:
if (data.indexOf('role') > 0) {
data.splice(data.indexOf('role'), 1);
data.unshift('role');
}
References:
Array.indexOf().
Array.prototype.splice().
Array.unshift().
Here is an immutable solution if needed :
const newData = [
data.find(item => item === 'role'),
...data.filter(item => item !== 'role'),
],
If you don't want to alter the existing array, you can use ES6 destructuring with the filter method to create a new copy while maintaining the order of the other items.
const data = ["email", "role", "type", "name"];
const newData = ['role', ...data.filter(item => item !== 'role')];
If you have an array of objects you could shift the start-index with splice and push. Splice replaces the original array with the part of the array starting from the desired index and returns the part it removes (the stuff before the index) which you push.
let friends = [{
id: 1,
name: "Sam",
},
{
id: 2,
name: "Steven",
},
{
id: 3,
name: "Tom",
},
{
id: 4,
name: "Nora",
},
{
id: 5,
name: "Jessy",
}
];
const tomsIndex = friends.findIndex(friend => friend.name == 'Tom');
friends.push(...friends.splice(0, tomsIndex));
console.log(friends);
To check whether an item exists in an array you should to use .includes() instead of in (as already noted here, in is for properties in objects).
This function does what you are looking for:
(removes the item from the position it is in and reads
in front)
data = ["email","role","type","name"];
moveToFirst("role", data);
function moveToFirst( stringToMove, arrayIn ){
if ( arrayIn.includes(stringToMove) ){
let currentIndex = arrayIn.indexOf(stringToMove);
arrayIn.splice(currentIndex, 1);
arrayIn.unshift(stringToMove);
}
}
console.log(data);
Similar to #Tandroid's answer but a more general solution:
const putItemsFirst = ({ findFunction, array }) => [
...array.filter(findFunction),
...array.filter(item => !findFunction(item)),
];
Can be used like this
putItemsFirst({
array: ["email","role","type","name"],
findFunction: item => item === 'role',
})
Something similar to this is what I ended up using,
I would go with this ES6 solution. It doesn't mutate the original array(considering it's not nested), doesn't traverse through the array(filter) and you're not just limited to 0th index for shifting the array item.
const moveArrayItem = (array, fromIndex, toIndex) => {
const arr = [...array];
arr.splice(toIndex, 0, ...arr.splice(fromIndex, 1));
return arr;
}
const arr = ["a", "b", "c", "d", "e", "f", "g"];
console.log(moveArrayItem(arr, 4, 0))
// [ 'e', 'a', 'b', 'c', 'd', 'f', 'g' ]
The most readable way in my opinion.
array.sort((a, b) => (a === value && -1) || (b === value && 1) || 0)
var data= ["email","role","type","name"];
data.splice(data.indexOf("role"), 1);
data.unshift('role');
You could take the delta of the check with the wanted value at top.
var data = ["email", "role", "type", "name"];
data.sort((a, b) => (b === 'role') - (a === 'role'));
console.log(data);
A reusable ES6/Typescript solution:
const moveToStart = <T>(array: T[], predicate: (item: T) => boolean): T[] => {
return array.sort((a, b) => {
if (predicate(a)) return -1;
if (predicate(b)) return 1;
return 0;
});
};
const data = ["email", "role", "type", "name"];
const result = moveToStart(data, (item) => item === "role"))
the in operator is about properties, not about items in arrays. See How do I check if an array includes an object in JavaScript? for what to use else.
You're missing braces around the two (!) statements in your if-block
I'm not sure whether that .remove() function you're using does take an index of an item.
Using lodash _.sortBy. If the item is role, it will be sorted first, otherwise second. This works fine too if there is no role
var data = ["email", "role", "type", "name"];
var sorted = _.sortBy(data, function(item) {
return item === 'role' ? 0 : 1;
});
console.log(sorted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Just wanted to drop this on here since according to other comments Guffa's answer seems to be gaining traction, the final tertiary - which was one of the negative comments on that answer is unnecessary. Also using arrow functions makes it seem much cleaner.
Also, it is easily expandable to handling Arrays of objects.
const first = "role";
data.sort((x, y) => first === x ? -1 : first === y)
I believe this should also handle the worry of the rest of the array being affected. When the sort function returns a number less than 0 (first === x), the element will move toward the start of the Array, when it returns 0 (first !== y), there will be no movement, and when a number greater than 0 (first === y), x will move toward the end of the Array, all in relation to x and y. Therefore, when neither x or y are equivalent to the desired first element (or it's identifier in the case of sorting objects), there will be no movement of the two in relation to each other.
For an object:
const unsorted = [{'id': 'test'}, {'id': 'something'}, {'id': 'else'}];
const first = 'something';
const sorted = unsorted.sort((x,y) => x['id'] === first ? -1 : y['id'] === first);
My solution is a bit different as it mutates original array instead of creating a new one.
It will move given item to start of the array and move item that was previously at start in the place of requested item.
function moveElementToStart<T>(items: T[], item: T) {
const itemIndex = items.indexOf(item);
// Item is not found or it is already on start
if (itemIndex === -1 || itemIndex === 0) return;
// Get item that is currently at start
const currentItemAtStart = items[0];
// Swap this item position with item we want to put on start
items[0] = item;
items[itemIndex] = currentItemAtStart;
}
Generalized one-liners:
const data = ["a", "b", "c", "d", "e", "f"];
const [from, take] = [3, 2];
data.unshift(...data.splice(from, take));
// alternatively
data = [...data.splice(from, take), ...data];
// ["d", "e", "a", "b", "c", "f"]
const moveToFront = (arr, queryStr) =>
arr.reduce((acc, curr) => {
if (queryStr === curr) {
return [curr, ...acc];
}
return [...acc, curr];
}, []);
const data = ['email', 'role', 'type', 'name'];
console.log(moveToFront(data, 'role'))
const moveTargetToBeginningOfArray = (arr, target) => {
// loop through array
for (let i = 0; i < arr.length; i++){
// if current indexed element is the target
if(arr[i] === target){
// remove that target element
arr.splice(i, 1)
// then add a target element to the beginning of the array
arr.unshift(target)
}
}
return arr;
};
// quick sanity check, before and after both are correct
const arrayOfStrings = ["email", "role", "type", "name", "role", "role"];
console.log('before:', arrayOfStrings)
console.log('after:', moveTargetToBeginningOfArray(arrayOfStrings, "role"))
// this would also work for numbers
var arrayOfNumbers = [2,4,0,3,0,1,0]
console.log('before:', arrayOfNumbers)
console.log('after:', moveTargetToBeginningOfArray(arrayOfNumbers, 0))
function unshiftFrom(arr, index) {
if (index > -1 && index < arr.length) { // validate index
var [itemToMove] = arr.splice(index, 1)
arr.unshift(itemToMove)
}
return arr // optional
}
//we can do this from scratch
let tempList=["person1","person2","person3"];
let result=[];
//suppose i need to move "person2" to first place
let movableValue=null;
let query="person2"; //here you could use any type of query based on your problem
tempList.map((e)=>{
if(e!==query){
result.push(e);
}else if(e===query){
movableValue=e;
}
})
if(movableValue!==null){
result.unshift(movableValue);
}
console.log(result)
)
var i = -1;
while (i < data.length) {
if (data[i] === "role") {
data.splice(i, 1);
break;
}
i++;
}
data.unshift("role");
indexOf only has limited browser support, not being recognized by IE7-8. So I wouldn't use it if I were you, even at the expense of a few lines' worth of code conciseness. You also want to put a semicolon at the end of the "unshift" statement. splice()'s first argument specifies the index to start removing elements, and the second argument specifies the number of arguments to remove.
data.unshift(data.splice(data.indexOf('role'), 1)[0])
data.indexOf('role') will find the index of 'role' in the array and then the original array is spliced to remove the 'role' element, which is added to the beginning of the array using unshift
var data= ["email","role","type","name"];
if ("role" in data) data.splice(data.indexOf("role"),1); data.unshift("role");
data;

Categories