skip to Main Content

So I have this function:

export default function getObjectFromTwoArrays(keyArr: Array<any>, valueArr: Array<any>) {
  // StartPoint:
  //  [key1,key2,key3],
  //  [value1,value2,value3]
  //
  // EndPoint: {
  //  key1: value1,
  //  key2: value2,
  //  key3: value3
  // }

  if (keyArr.length === valueArr.length) {
    // @ts-ignore
    return Object.assign(...keyArr.map((el,index) => ({[el]: valueArr[index]})))
  } else {
    throw new Error(`Arrays should be the same length: ${{keyArr}}, ${{valueArr}}`)
  }
}

So me need to get exact this result from example above – EndPoint.
I tried to expand to a variable, got the same issue.

I tried to to replace with: Object.assign({...keyArr.map((el,index) => ({[el]: valueArr[index]}))})

But the result will be: {0: {key1: value1}, 1: {key2: value2}}

Also with Object.assign([...keyArr.map((el,index) => ({[el]: valueArr[index]}))])

Result: [{key1: value1}, {key2: value2}]

2

Answers


  1. Based on the name of your parameters it looks like you’re trying to take an array of keys and an array of values and turn it into an object. But Object.assign takes two parameters: a source and a target. Neither of which should be an array. You want Object.fromEntries, but first you need to combine the two arrays into a single array of key/value pairs:

    const zip = (xs, ys) => {
      if (xs.length === ys.length) {
        return xs.map((x, i) => [x, ys[i]]);
      } else {
        throw new Error('cannot merge arrays of unequal length');
      }
    };
    
    const getObjectFromTwoArrays = (keys, values) => Object.fromEntries(zip(keys, values));
    

    The Object.fromEntries method takes an array of key/value pairs and turns it into an object, it is the converse of Object.entries. See:

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries

    Login or Signup to reply.
  2. The Object.assign method takes at least one parameter, but in your function the array you were spreading could have been empty. The key part in the error message is "must be passed to a rest parameter", and from the various overload signatures the one you’d want to use is assign(target: object, ...sources: any[]): any;. To avoid the need for // @ts-ignore, you’d write

    return Object.assign({}, ...keyArr.map((el,index) => ({[el]: valueArr[index]})))
    //                   ^^^
    

    (Playground demo)

    However, you really should not use Object.assign for this. What you want is Object.fromEntries, which takes an iterable of tuples:

    export default function getObjectFromTwoArrays(keyArr: Array<any>, valueArr: Array<any>) {
      if (keyArr.length === valueArr.length) {
        return Object.fromEntries(keyArr.map((key, index) => [key, valueArr[index]]))
      } else {
        throw new Error(`Arrays should be the same length: ${{keyArr}}, ${{valueArr}}`)
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search