2

I have an array of elements containing iPhone models and 4 values that come after it, like this:

const arr = ['ip6s+', '35', '15',  '10', '10', 'ip7', '40', '20', '15', '15']

I want to turn this into an object that looks like this:

const Obj = {
   'ip6s+': ['35', '15',  '10', '10'],
   'ip7+' : ['90', '60', '35', '30']
}

Where the first object is the phone model and every fourth is its values. How to do that?

5 Answers 5

5

You can use slice:

const arr = ['ip6s+', '35', '15',  '10', '10','ip7', '40', '20', '15','15'];

const obj = {};

const n = 4; // the number of values after the model name

for (var i = 0; i < arr.length; i += n + 1) {
  obj[arr[i]] = arr.slice(i + 1, i + n + 1);
}

console.log(obj);

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

5 Comments

but what if the array has more values ?
@ths I'm under the impression that the array will always have the specified format ([model1, v1, v2, v3, v4, ...]), since the OP didn't mention any more information.
but providing more feature-proof answers will provide a better assistance for anyone seeking to know how to get some items from an array for example.
@ths You're right, but I think that this is a very specific example, a special, not a general case, the only generalization I can see is probably the variability of the number of values after the model name, in which case only the increments to the loop counter and the slicing parameters will have to be modified.
@MrGeek I agree, this is a very specific example. To me, the question looks like a homework question, so the answer should have some schema.
1

You could also use reduce()

const arr = ['ip6s+', '35', '15',  '10', '10','ip7', '40', '20', '15','15']
let lastCurr = null;
const result = arr.reduce( ( res, curr, ix ) => {
  if( 0 == ix % 5 ){
    res[ curr ] = [];
    lastCurr = curr;
  }else 
    res[ lastCurr ].push( curr );
  return res;
}, {} )

Comments

1

If your keys are always supposed to be isNaN and first value always corresponds to key, than you can do something like this, this will be more dynamic in case there are dynamic number of elements between two keys

const arr = ['ip6s+', '35', '15', '10', '10', 'ip7', '40', '20', '15', '15']

let getDesiredFormat = (arr) => {
  let currentKey = arr[0]
  let final = arr.reduce((op, inp) => {
    if (isNaN(inp)) {
      op[inp] = []
      currentKey = inp
    } else {
      op[currentKey].push(inp)
    }
    return op
  }, {})
  return final
}

console.log(getDesiredFormat(arr))

Comments

1

If the array starts with an item that starts with "ip" and starting with that is the trigger for a new key in the object, you could use startswith.

This allows a variable number of items after ip.

const arr = ['ip6s+', '35', '15', '10', '10', 'ip7', '40', '20', '15', '15'];
const obj = {};
let currKey = arr.slice(0, 1);
arr.forEach(s => s.startsWith("ip") ? (currKey = s, obj[s] = []) : obj[currKey].push(s));
console.log(obj);

Comments

0

Use slice method, also the following example should work no matter how many elements in the array :

this should work also if there are elements before 'ip6s+' BUT the 'ip6s+' must always precede 'ip7'.

const arr = ['some', 'elemnts', 'in', 'front', 'ip6s+', '35', '15', 'abc', '80', '58', '10', '10', 'ip7', '40', '20', '15', '15', '100', 'xyz'],
  l = arr.length,
  ip6sIndex = arr.indexOf('ip6s+'),
  ip7Index = arr.indexOf('ip7'),
  obj = {};
  
obj[arr[ip6sIndex]] = arr.slice(ip6sIndex + 1, ip7Index); /** get the items after 'ip6s+' **/
obj[arr[ip7Index]] = arr.slice(-(l - ip7Index) + 1); /** get the items after 'ip7' **/

console.log(obj);

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.