1

I am trying to do sort inside the reduce and I thought I have everything correct but still my result is not sorted as desired.

Here is the code snippet I have:

var studentInfo = [
{
    studentId: 1,
    addresses: [
        {street: '123 Main St'},
    ]
},
{
    studentId: 2,
    addresses: [
        {street: '456 Front St'}
    ]
},
{
    studentId: 3,
    addresses: [
        {street: '100 MLK St'}
    ]
}
];

function appendAddress(studentId, newAddress) {
  return studentInfo.reduce(function (info, student) {
    if (student.studentId === studentId) {
        student = {
            studentId: student.studentId,
            addresses: student.addresses.concat(newAddress).sort(function (address1, address2) {
                return address2.street - address1.stree;
            })
        };
    }
    info.push(student);

    return info;
}, []);
}

var newAddress = {
street: '166 Devil St'
}

console.log('Result: ' + JSON.stringify(appendAddress(2, newAddress)));

I am getting result as

Result: [{"studentId":1,"addresses":[{"street":"123 Main St"}]},{"studentId":2,"addresses":[{"street":"456 Front St"},{"street":"166 Devil St"}]},{"studentId":3,"addresses":[{"street":"100 MLK St"}]}]

instead of

Result: [{"studentId":1,"addresses":[{"street":"123 Main St"}]},{"studentId":2,"addresses":[{"street":"166 Devil St"},{"street":"456 Front St"}]},{"studentId":3,"addresses":[{"street":"100 MLK St"}]}]

Am I missing anything?

2
  • 2
    There's a typo in your sort: stree instead of street. You're also substracting two strings which will result in NaN Commented Jan 16, 2018 at 17:17
  • 2
    It seems like you're just trying to add a new address to an existing student, and add the student if it's not yet there. Is that right? If so, why use .reduce() and .sort()? Maybe you could explain exactly what you're trying to accomplish. Commented Jan 16, 2018 at 17:18

1 Answer 1

1

As to the sorting issue, if that was the main thing you were wondering about, you do indeed have a typo as the comment above noted, and also, performing subtraction on non-numeric strings won't get you very far. I used .localeCompare in the solution above.

If you wanted to copy the objects as you were appending, that can still be done more simply, but I don't know if that's what you actually want.

var studentInfo = [
  {studentId: 1,addresses: [{street: '123 Main St'}]},
  {studentId: 2,addresses: [{street: '456 Front St'}]},
  {studentId: 3,addresses: [{street: '100 MLK St'}]}
];

console.log(addAddress(2, {street: "1234 56th Ave"}));

function addAddress(studentId, address) {
  const idx = studentInfo.findIndex(o => o.studentId === studentId);
  if (idx !== -1) {
    return [...studentInfo.slice(0, idx), {
      studentId,
      addresses: [...studentInfo[idx].addresses, address].sort((a,b) => a.street.localeCompare(b.street))
    }, ...studentInfo.slice(idx+1)];
  } else {
    return [...studentInfo, {studentId, addresses:[address]}];
  }
}

But now you're having two different copies of the data with some shared objects.

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

4 Comments

i was looking to append if student already exist otherwise create new one.
@αƞjiβ: Yes, I know. That's what I wrote. I added another solution to more closely resemble your original result where objects that were mutated are now copied instead. Are you taking an immutable approach to your code?
I see. Then the second solution prevents mutation.
I removed the first solution, and tweaked the no-mutation version.

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.