javascript insert object to array at specific point id and increment others id


javascript insert object to array at specific point id and increment others id



I have little problem with js arrays. I want to insert object on if statement and increase id on anothers objects




var arr=[{asc_id:1, date:2018-06-29, name:"first"},
{asc_id:2, date:2018-06-30, name:"second"},
{asc_id:3, date:2018-07-10, name:"fourth"},
{asc_id:4, date:2018-07-10, name:"fifth"}];
var checkedItem={asc_id:4, date:2018-06-30, name:"third"};

let savingDate = moment(checkedItem.date)
var newArr = arr.map((item,key)=>{
if(savingDate.isSame(item.date) || savingDate.isAfter(item.date)){
console.log(true)
return{
//code here
}
}else{
return{
//code here
}
console.log(false)
}
})
console.log(newArr)



i want make new array looks like


newArr=[{asc_id:1, date:2018-06-29, name:"first"},
{asc_id:2, date:2018-06-30, name:"second"},
{asc_id:3, date:2018-06-30, name:"third"},
{asc_id:4, date:2018-07-10, name:"fourth"},
{asc_id:5, date:2018-07-10, name:"fifth"}];



map is not good idea? condition i check with momento and check statement is correct only i want how to push object between second and fourth and make asc_id as in code?





You're returning the same object in both if and else.
– Barmar
Jun 29 at 20:33


if


else





Is date supposed to be a string? It needs quotes around it.
– Barmar
Jun 29 at 20:35


date





ok i update with real statement
– Piotr Bieszczad
Jun 29 at 20:37





You can't use .map() to add to an array, it always returns an array that's the same length as the original. You can use .splice() to insert into an array.
– Barmar
Jun 29 at 20:37


.map()


.splice()





Bermar any ideas?
– Piotr Bieszczad
Jun 29 at 20:44




5 Answers
5



What you can do is make a deep copy of the original array. Then insert the new element in that array at the appropriate place, and then reset all the asc_id properties.


asc_id




var arr=[{asc_id:1, date:"2018-06-29", name:"first"},
{asc_id:2, date:"2018-06-30", name:"second"},
{asc_id:3, date:"2018-07-10", name:"fourth"},
{asc_id:4, date:"2018-07-10", name:"fifth"}];
var checkedItem={asc_id:4, date:"2018-06-30", name:"third"};

var newArr = arr.map(e => Object.assign({}, e));
var insertPos = newArr.findIndex(({date}) => date > checkedItem.date);
if (insertPos == -1) { // If not found, insert at end
insertPos = newArr.length;
}
newArr.splice(insertPos, 0, checkedItem);
newArr.forEach((e, i) => e.asc_id = i + 1);
console.log(newArr);





Would incorrectly insert if the new item is the last item, try it with a date in 2019
– HMR
Jun 29 at 21:27





@HMR Good catch, added a check for that.
– Barmar
Jun 29 at 21:33



.map is not a good idea because it returns an array with the same length as the one mapped, you can use a simple for loop and create an empty array to fill it with values from original array and push the checkedElement whenever matched , for the asc_id create a ndx and increment it:


.map


for


checkedElement


asc_id


ndx




var arr=[{asc_id:1, date:'2018-06-29', name:"first"},
{asc_id:2, date:'2018-06-30', name:"second"},
{asc_id:3, date:'2018-07-10', name:"fourth"},
{asc_id:4, date:'2018-07-10', name:"fifth"}];

var checkedItem={asc_id:4, date:'2018-06-30', name:"third"};

var newArr = , ndx = 0;

arr.forEach((e,i) => {
newArr.push({ ...e, asc_id : ++ndx })

if(e.date === checkedItem.date)
newArr.push({...checkedItem, asc_id : ++ndx })
})

console.log(newArr)





Item is never inserted if it's the last, try with a new item that has a date in 2019. It will also never insert if it's the first, try with date in 2017
– HMR
Jun 29 at 21:26



Other answers re index the entire array, I'm not sure that's what you want, the following uses reduce and will only re index items after the inserted item.




const arr = [
{ asc_id: 5, date: "2018 - 06 - 29", name: "first" },
{ asc_id: 6, date: "2018 - 06 - 30", name: "second" },
{ asc_id: 8, date: "2018 - 07 - 10", name: "fourth" },
{ asc_id: 9, date: "2018 - 07 - 10", name: "fifth" }
];
const checkedItem = { asc_id: "ignored", date: "2018 - 06 - 30", name: "third" };

const addItem = (arr,newItem)=>{
let itemInserted=false;
const newArray = arr.reduce(
(result,item) => {
if(newItem.date.localeCompare(item.date) === -1){
if(!itemInserted){//item has not been inserted yet
result.push({...newItem,asc_id:item.asc_id});
itemInserted=true;
}
result.push({...item,asc_id:item.asc_id+1})
}else{
result.push(item)
}
return result;
},
//initial result
);
if(!itemInserted){//new item was the last item
newArray.push({...newItem,asc_id:arr.slice(-1)[0].asc_id+1});
}
return newArray;
}
console.log(addItem(arr,checkedItem));



Probably you could start implementing a function like the one I provide as part of the following runnable snippet.



Note that the first parameter is a condition: use moment or whatever to parse a date or operate with any property of any of the existing items.


moment



See how insertWhen is a high order function which takes two different functions cond and comparer:


insertWhen


cond


comparer


cond


compare


-1


1


moment


-1


1




const arr = [{
asc_id: 1,
date: '2018 - 06 - 29',
name: "first"
},
{
asc_id: 2,
date: '2018 - 06 - 30',
name: "second"
},
{
asc_id: 3,
date: '2018 - 07 - 10',
name: "fourth"
},
{
asc_id: 4,
date: '2018 - 07 - 10',
name: "fifth"
}
]

const insertWhen = (cond, comparer, newItem, arr) => {
const foundItem = arr.find(cond)

if (!foundItem) return

let foundItemIndex = arr.indexOf(foundItem)

switch (comparer(foundItem, newItem)) {
case -1:
arr.splice(foundItemIndex + 1, 0, newItem)

arr.slice(foundItemIndex + 1)
.forEach(item => (item.asc_id = ++foundItemIndex + 1))
break

case 1:
arr.splice(foundItemIndex, 0, newItem)

arr.slice(foundItemIndex)
.forEach(item => (item.asc_id = ++foundItemIndex))
break

}
}

var newItem = {
asc_id: 4,
date: '2018-06-30',
name: "third"
}

insertWhen(
({ date }) => date == '2018 - 06 - 30',
(foundItem, newItem) => -1, // INSERT AFTER, wins foundItem
newItem,
arr
)

console.log(arr)




const arr = [{
asc_id: 1,
date: '2018 - 06 - 29',
name: "first"
},
{
asc_id: 2,
date: '2018 - 06 - 30',
name: "second"
},
{
asc_id: 3,
date: '2018 - 07 - 10',
name: "fourth"
},
{
asc_id: 4,
date: '2018 - 07 - 10',
name: "fifth"
}
]

const insertWhen = (cond, comparer, newItem, arr) => {
const foundItem = arr.find(cond)

if (!foundItem) return

let foundItemIndex = arr.indexOf(foundItem)

switch (comparer(foundItem, newItem)) {
case -1:
arr.splice(foundItemIndex + 1, 0, newItem)

arr.slice(foundItemIndex + 1)
.forEach(item => (item.asc_id = ++foundItemIndex + 1))
break

case 1:
arr.splice(foundItemIndex, 0, newItem)

arr.slice(foundItemIndex)
.forEach(item => (item.asc_id = ++foundItemIndex))
break

}
}

var newItem = {
asc_id: 4,
date: '2018-06-30',
name: "third"
}

insertWhen(
({ date }) => date == '2018 - 06 - 30',
(foundItem, newItem) => 1, // INSERT BEFORE, wins the new item
newItem,
arr
)

console.log(arr)





Item will never be inserted if it's the last, try it with a new item that has a date in 2019
– HMR
Jun 29 at 21:23





@HMR Maybe I'm mistaken, but it seems like the OP wants to insert an item between some given date or after one. I don't know if the OP wants to insert the item as the last one if cond is never true.
– Matías Fidemraizer
Jun 29 at 22:42


cond


true





@HMR BTW, what has to do the date in 2019? For me, it seems like I should refactor the snippet so it uses a comparer instead of a condition, so the comparer may decide if it goes before or after the found item.
– Matías Fidemraizer
Jun 29 at 22:54


arr.slice(0,idx).concat([element_to_insert].concat(arr.slice(idx+1,arr.length).map(n=>{
n.asc_id++;
return n;
})))





How does this increment the asc_id in the elements after the one that's inserted?
– Barmar
Jun 29 at 20:39


asc_id





@Barmar valid, I modified it a bit
– JayB
Jun 30 at 3:55





Yuo also need to fix the asc_id of the element that you insert, so it's in the proper sequence for the place it gets.
– Barmar
2 days ago


asc_id






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift