2

I am working on project where I need to maintain an array from json data returned from API, json can have tree, I have following code which is working fine but I wan to remove if conditions before assigning values to array elements

// data contains json 
let newArray = []
for(let d in data){
    for(let x in data[d]){
        if(typeof(newArray[d]) === 'undefined'){
            newArray[d] = []
        }
        if(typeof(newArray[d][data[d][x]['id']]) === 'undefined'){
            newArray[d][data[d][x]['id']] = []
        }
        newArray[d][data[d][x]['id']]['price'] = data[d][x]['price']
        newArray[d][data[d][x]['id']]['discount'] = data[d][x]['discount']
    }
}

In above code I have to check the array first and declare it as array if its not otherwise it returns undefined error, is there any way to get rid of there conditions and extend array as per requirement ?

6
  • newArray[d] looks suspicious. I hope newArray will not become a sparse array? (if so, use an object instead) You can make the code more DRY by storing the repetitive expressions in variables Commented Aug 23, 2019 at 8:50
  • You seem to be using arrays as normal objects. What is data[d][x]['id'] ? Is it a string or is it a number ?
    – Titus
    Commented Aug 23, 2019 at 9:06
  • @Titus it can be anything from string or number, I did check with let newArray = {} but it has same issue
    – Vikram
    Commented Aug 23, 2019 at 9:15
  • 1
    It should be an object in the first place, not an array. JavaScript allows you to do sth like: let arr = []; arr['prop1'] = 'val1'; without complaining. But the problem is with serialization. If you try to JSON.stringify() such a thing, only number-like indexes will be kept in the result. For storing key-value pairs there are object literals ({ key1: 'value1' }) and this is what you should use here. Regarding your case, if you expect that let o = {}; o.prop1.prop2 = 'val1' will create { prop1: { prop2: 'val1' } } then the answer is no, you can't do that without additional effort. Commented Aug 23, 2019 at 9:32
  • 1
    @SebastianKaczmarek Thanks for explanation, it seems that using conditions is only solution in my case, however I can try with object at other places though
    – Vikram
    Commented Aug 23, 2019 at 11:58

2 Answers 2

2

You can you new ES6 spread operator like this

newAraay[d] = [...newArray,...Array(data[d][x]['id']),[...Array('price',data[d][x]['price'])]]

Like here in this snippet I am directly doing abc[1][3][4] = "new value" without explicitly initialising them

let abc = [];
abc[1]=  [...abc,...Array(3),[...Array(4),'new inserted value']]
console.log(abc);

4
  • 1
    It should be rather: abc[1]= [...abc, ...Array(3),[...Array(4),'new inserted value']]. Otherwise, when you try to do something like this: abc[1]= [...Array(2),[...Array(4),'new inserted value']] after first assing then it will be overridden Commented Aug 23, 2019 at 9:43
  • @SebastianKaczmarek do you mean abc will be overridden ?
    – Aviso
    Commented Aug 23, 2019 at 9:46
  • 1
    Not the whole array, but the 1 index will be, if you try to do abc[1][3][4] = 'newvalue' and then abc[1][2][3] = 'anothervalue' Commented Aug 23, 2019 at 9:48
  • yes , you are right ! I will edit the anwer , Thanx :)
    – Aviso
    Commented Aug 23, 2019 at 9:51
1
newArray[d] = newArray[d] || []

You can understand this operation in this post

Or use Lodash Library

https://lodash.com/docs/4.17.11#set

1
  • its a declaration again, I want to be able to assign value, also it might work on first level element but not for inner elements like newArray[d][e][f] if I want to
    – Vikram
    Commented Aug 23, 2019 at 9:03

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.