1

I'm trying to translate javascript to swift. This is the javascript method:

export function serializeProperty(
      properties: Map<Key, Value | null>,
    ): Array<[Key, JsonValue | null]> {
      const data = Array.from(properties.entries());
      const processedData = data.map(entry => {
        const [key, value] = entry;
        if (value != null) {
          return [key, serializeValue(value)];
        }
        return [key, null];
      });
      return processedData;
    }
export function serializeValue(Value: Value): JsonValue {
  if (Value.type === 'string') {
    return {type: 'string', value: Value.value.toJson()};
  } else if (Value.type === 'array_node') {
    return {
      type: 'array_node',
      value: Value.value.map(node => node.toJson()),
    };
  }
  return Value;
}

I have translated it in swift like below:

func serializeProperty(properties: [Key: Value?]) -> [[Key: JsonValue?]]? {

  var data: [[Key: JsonValue?]]?

  guard let propertiesJson = properties else { return data }
  for property in propertiesJson {
    for item in property {
      if let unwrappedValue = item.value {
        properties[item.key] = try serializeValue(valueJson: unwrappedValue)
      }
    }
  }

  return data
}

I'm getting the error on this line : guard let propertiesJson = properties else { return data } Is the translation to swift correct or am I missing something?

userNew
  • 11
  • 3
  • For a translation, the variable names don't appear to match between the two snippets – Bergi Nov 02 '21 at 02:50
  • While I don't know Swift, I'm missing either the array, the tuple, or the map type in your translation. – Bergi Nov 02 '21 at 02:52
  • What is the definition of `serializeValue` (in TypeScript)? – msbit Nov 02 '21 at 03:05
  • 1
    @msbit i have updated the question with the method – userNew Nov 02 '21 at 03:20
  • ‘guard let’ needs an optional (thus the error). You are trying to use it with a non-optional dictionary with values that are optionals. On your TypeScript, you don’t do a null check until you’re inside your map function. Swift has map, too, by the way. – jnpdx Nov 02 '21 at 03:26
  • @jnpdx can you please suggest how i can replace the swift method using map? – userNew Nov 02 '21 at 03:31

1 Answers1

1

The simplest translation of this TypeScript to Swift will look something like:

func serializeProperty(properties: Dictionary<Key, Value?>) -> Array<(Key, JsonValue?)> {
  let processedData = properties.map() { key, value -> (Key, JsonValue?) in
    if let value = value {
      return (key, serializeValue(value: value))
    }   

    return (key, nil)
  }
  return processedData
}

Note the use of (Key, JsonValue?) in regular parentheses to denote a tuple of Key and JsonValue?, matching the TypeScript notation of [Key, JsonValue | null]. Also note that in both the TypeScript and Swift implementations, the properties parameter is a non-nullable type, so there is no need to check against null/nil.

Using a guard clause and returning the result of properties.map() directly, this can be further simplified to:

func serializeProperty(properties: Dictionary<Key, Value?>) -> Array<(Key, JsonValue?)> {
  return properties.map() { key, value in
    guard let value = value else { return (key, nil) }

    return (key, serializeValue(value: value))
  }
}

Going back the other way, the TypeScript implementation can also be simplified in a similar way to:

function serializeProperty(properties: Map<Key, Value|null>): Array<[Key, JsonValue|null]> {
  return Array.from(properties.entries()).map(([key, value]) => {
    if (value === null) { return [key, null]; }

    return [key, serializeValue(value)];
  }); 
}
msbit
  • 4,152
  • 2
  • 9
  • 22