1

I get in response an array with deposits, and I need to get depositId, but multicurrency deposits have an array of several deposits. (First array) As a result, I need to have an array with deposits, without linkedDeposits. (On the example of the second array) I just can’t figure out how to do this

[ {
    depositId: 1111, 
    depositName: 'Test',
    depositCur: 'RUB'
}
,
{
    depositName: 'Test',
    linkedDeposits: [ {
        depositName: 'Test',
        depositId: 2222, 
        sepositName: 'Test RUB', 
        depositCur: 'RUB'
    }
    ,
    {
        depositName: 'Test',
        depositId: 3333, 
        sepositName: 'Test USD', 
        depositCur: 'USD'
    }
    ,
    ]
}
]
[ {
    depositId: 1111, 
    depositName: 'Test',
    depositCur: 'RUB'
}
,
{
   depositName: 'Test',
   depositId: 2222, 
   sepositName: 'Test RUB', 
   depositCur: 'RUB'
}
,
{
   depositName: 'Test',
   depositId: 3333, 
   sepositName: 'Test USD', 
   depositCur: 'USD'
}
]
3
  • The original will always be in such structure or there can be more element ? Commented Oct 7, 2019 at 12:36
  • What have you tried so far? Commented Oct 7, 2019 at 12:37
  • 1
    Have a look at Array.prototype.flatMap() Commented Oct 7, 2019 at 12:44

6 Answers 6

4

You could just check if depositId exists then add item else add linkDeposits array into final array:

var data = [ {
    depositId: 1111, 
    depositName: 'Test', 
    depositCur: 'RUB'
}, {
    depositName: 'Test',
    linkedDeposits: [ {
        depositName: 'Test',
        depositId: 2222, 
        sepositName: 'Test RUB', 
        depositCur: 'RUB'
    },{
        depositName: 'Test',
        depositId: 3333, 
        sepositName: 'Test USD', 
        depositCur: 'USD'
    }]
}];

var result = [];
data.forEach(function(item){
    if (item.depositId)
       result.push(item);
    else
       result = result.concat(item.linkedDeposits);
});

console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

1

One more solution that I find elegant since it doesn't mutate original array, nor any array:

// Simplified data to focus on actual answer.
const data = 
  [ { id: 1111 }
  , { linkedDeposits: [ { id: 2222 }, { id: 3333 } ] }
  ]

const newData = data.flatMap(deposit =>
  deposit.linkedDeposits || deposit
)

console.log(newData)

See array.flatMap() for more details about this method.

Beware, this function is part of ES2019 ecosystem and might not be available for all users. See browsers compatibility.

enter image description here

8 Comments

Could you use the original data ?
I'd rather focus on the answer part. However, this would work with original data as well. I hope this is not why you downvoted :/
I actually wanted to upvote for the use of flatMap, sorry about that ! But, still, could you use the original data ?
Just for the "one-liner"-fraction: deposit.linkedDeposits ? deposit.linkedDeposits : deposit can be reduced to deposit.linkedDeposits || deposit
@Andreas As per SOF guidelines, it's better to include relevant information into the answer (in case the website is down for some reason). An anyway, it's always nicer to not have to open a link and just see it in the answer !
|
1

here is my take on your issue.

Start by reducnig your array, then remove the deposits that still contains inner deposits. That leaves you with the expected result.

const original = [{
  depositId: 1111,
  depositName: 'Test',
  depositCur: 'RUB'
}, {
  depositName: 'Test',
  linkedDeposits: [{
    depositName: 'Test',
    depositId: 2222,
    sepositName: 'Test RUB',
    depositCur: 'RUB'
  }, {
    depositName: 'Test',
    depositId: 3333,
    sepositName: 'Test USD',
    depositCur: 'USD'
  }]
}];

const modified = original.reduce(
  // Maryannah's solution (less compact)
  // (p, n) => (Array.prototype.concat.apply([], [...p, ...(n.linkedDeposits || []), n])),
  // CodeManiac's solution
  (p, n) => [...p, ...(n.linkedDeposits || []), n],
  []
).filter(deposit => !deposit.linkedDeposits);

console.log(modified);

(The code is minified to its maximum though.)

3 Comments

can be minified further i guess, (p, n) => [...p, ...(n.linkedDeposits || []), n],...
@CodeManiac not sure it flattens the array by doing so. Care to make a snippet out of it ?
0

You can use reduce method, like this:

const data = [{
	depositId: 1111,
	depositName: 'Test',
	depositCur: 'RUB'
}, {
	depositName: 'Test',
	linkedDeposits: [{
		depositName: 'Test',
		depositId: 2222,
		sepositName: 'Test RUB',
		depositCur: 'RUB'
	},
	{
		depositName: 'Test',
		depositId: 3333,
		sepositName: 'Test USD',
		depositCur: 'USD'
	}]
}]

const result = data.reduce((acc, elem) => {
	!elem.hasOwnProperty('linkedDeposits') ? acc.push(elem) : elem.linkedDeposits.forEach(el => acc.push(el))
	return acc
}, [])

console.log(result)

Comments

-1
let tempVal = [ {
    depositId: 1111, 
    depositName: Test, 
    depositCur: RUB
}
,
{
    depositName: Test,
    linkedDeposits: [ {
        depositName: Test,
        depositId: 2222, 
        sepositName: Test RUB, 
        depositCur: RUB
    }
    ,
    {
        depositName: Test,
        depositId: 3333, 
        sepositName: Test USD, 
        depositCur: USD
    }
    ,
    ]
}
]

let newArray = [];
for(let i = 0; tempVal.length > i; i++){
if(tempVal[i].depositId != null && tempVal[i].depositId != undefined){
  this.newArray({depositId: tempVal[i].depositId, depositName: tempVal[i].depositName, depositCur: tempVal[i].depositCur})
}
if(tempVal[i].linkedDeposits.length > 0){
  for(let j = 0; tempVal[i].linkedDeposits.length > j;j++){
  if(tempVal[i].linkedDeposits[j].depositId != null && tempVal[i].linkedDeposits[j].depositId != undefined){
  this.newArray({depositId: tempVal[i].linkedDeposits[j].depositId, depositName: tempVal[i].linkedDeposits[j].depositName, depositCur: tempVal[i].linkedDeposits[j].depositCur})
   }
  }
}
}

1 Comment

you're doing alot of unecessary calculations and loops without using ANY js arrays method... its like writing it in C -.-
-1

Use the array.forEach() to loop on all deposites, if they have linkedDeposites array - concat it to result array. else- push the single deposite to result array.

let res = [];
sourceArr.forEach( deposite => {
  if( deposite.hasOwnProperty('linkedDeposites') )
     res = res.concat(deposite.linkedDeposites);
  else
    res.push(deposite);
});

NOTE: this will not work if any deposite inside "linkedDeposites" has its own "linkedDeposites". if that is the case comment down below and I'll rewrite my answer to take care of that as well.

2 Comments

concat doesn't auto add data into any array of its arg but it returns an array with merged value. So it should be res = res.concat(deposite.linkedDeposites);
@BilalSiddiqui you're right, tnx for the correction :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.