1

I have the following object:

{ name: ["Jimmy","Jill"], age: [23, 42], location: { city: ["LA", "NYC"] }

For every object key there is an array value with 2 entries (always). What I'm trying to do is to recreate the object by plucking the 2nd item in the arrays. But I want this to happen recursively. So the output would be:

{ name: "Jill", age: 42, location: { city: "NYC" }

I have tried iterating through the object using Object.keys() but this doesn't appear to give me nested keys. I was wondering if there was a more elegant way to tackle this?

Many thanks in advance.

1
  • 1
    Why isn't location an array like this [{city: 'LA'}, {city: 'NY'}]? How do fields nested deeper than 1 level work? Commented Mar 15, 2018 at 0:14

3 Answers 3

1

Is this considered okay? This only works if we assume every prop would either be an Array of a plain Object.

let o = { name: ["Jimmy","Jill"], age: [23, 42], location: { city: ["LA", "NY"] }}

function rec(obj) {
    for (let key in obj) {
        if (obj[key] instanceof Array) {
            obj[key] = obj[key][1]
        } else {
            obj[key] = rec(obj[key])
        }
    }
    return obj
}

rec(o)
console.dir(o)

Or even this? (allows existence of array that contains objects and plain primitive entries)

let o = {
    primitive: 10,
    name: ["Jimmy","Jill"],
    age: [23, 42],
    location: {
        city: ["LA", "NY"],
        test: [
            {prop1: ['1', '2']},
            {prop2: ['A', 'B']}
        ]
    }
}

function rec(obj) {
    if (obj instanceof Array) {
        return rec(obj[1])
    } else if (obj instanceof Object) {
        for (let key in obj) {
            obj[key] = rec(obj[key])
        }
        return obj
    } else {
        return obj
    }
}

rec(o)
console.dir(o)

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

3 Comments

This is beautiful. Thank you!
Also for anyone else seeing this, I was looking for the 2nd item in the arrays so rec(obj[1]) does the trick.
@GivP Yeah I totally ignored that. Fixed.
1

Might be easier to filter during parsing:

j = '{ "name": ["Jimmy","Jill"], "age": [23, 42], "location": { "city": ["LA", "NYC"] }}'

o = JSON.parse(j, (k, v) => v.constructor === Array ? v.pop() : v)

console.log( o )

1 Comment

Lovely and elegant!
0

Late to the party, but here's a "functional" option to consider. Would need to be modified to accommodate any edge cases.

const reducer = input =>
  Object.entries(input).reduce(
    (acc, [key, value]) =>
      value instanceof Array ? { ...acc, ...{ [key]: value[1] } } : { ...acc, ...reducer(value) },
    {}
  );

const input = { name: ["Jimmy", "Jill"], age: [23, 42], location: { city: ["LA", "NYC"] } };
const reduced = reducer(input);

console.log(reduced); // Output: { name: 'Jill', age: 42, city: 'NYC' }

Comments

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.