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 ?

Vikram
  • 3,171
  • 7
  • 37
  • 67
  • `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 – CertainPerformance Aug 23 '19 at 08: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 Aug 23 '19 at 09:06
  • @Titus it can be anything from string or number, I did check with `let newArray = {}` but it has same issue – Vikram Aug 23 '19 at 09:15
  • The code is confusing: could you share a bit of `data` content? Assuming `data` is an object, then `d` is a key, not an array index. But you're passing `d` to `newArray` a it is an index. If it's not, `newArray` should be an object. And if it is, you shouldn't use `for…in` for arrays: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Array_iteration_and_for...in I'm pretty sure the code can be improved and bugfixed, but you should add a bit of more context and information about `data` and the expected output. – ZER0 Aug 23 '19 at 09:27
  • 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. – Sebastian Kaczmarek Aug 23 '19 at 09: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 Aug 23 '19 at 11:58

2 Answers2

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);
Aviso
  • 695
  • 4
  • 12
  • 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 – Sebastian Kaczmarek Aug 23 '19 at 09:43
  • @SebastianKaczmarek do you mean abc will be overridden ? – Aviso Aug 23 '19 at 09: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'` – Sebastian Kaczmarek Aug 23 '19 at 09:48
  • yes , you are right ! I will edit the anwer , Thanx :) – Aviso Aug 23 '19 at 09: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

CodeBanBan
  • 48
  • 5
  • 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 Aug 23 '19 at 09:03