This topic describes how to obtain the value that corresponds to a specific key in a string that has no delimiters.

UDF used to obtain the value of a string that has no delimiters

UDFKeyValue(String str, String splitor1, String splitor2, String key)
  • Description: used to obtain the value that corresponds to a specific key in a string.
    Note This UDF is not suitable for a string that has delimiters. To obtain the value that corresponds to a specific key in a string that has delimiters, see UDFKeyValueEx.
  • Parameters:
    • str: the target string.
    • splitor1: the delimiter used to split the string to obtain key-value pairs. The default value of splitor1 is a semicolon (;).
    • splitor2: the delimiter used to split the obtained key-value pairs. The default value of splitor2 is a colon (:).

UDF example

  1. Function registration
    After UDFKeyValue.java passes the test, register it as a function.
    Note To publish a UDF to a server for production use, the UDF needs to go through packaging, uploading, and registration. You can use the one-click publish function to complete these steps. MaxCompute Studio allows you to run the mvn clean package command, upload a JAR package, and register the UDF in sequence. For more information, see Package、Upload and Register.
  2. Examples
    After the UDF is registered, execute one of the following statements:
    • Example 1
      select UDFKeyValue('a:1;b:2;','a') from dual;
      The result is as follows:
      +-----+
      | _c0 |
      +-----+
      | 1   |
      +-----+
    • Example 2
      select UDFKeyValue('a:1;b:2;','\;',':','a') from dual;
      The result is as follows:
      +-----+
      | _c0 |
      +-----+
      | 1   |
      +-----+

UDF code example

// The package name, which can be defined as needed.
package com.aliyun.odps.examples.udf;
import com.aliyun.odps.io.Text;
import com.aliyun.odps.udf.UDF;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class UDFKeyValue extends UDF{
        // Save all key-value pairs.
    private Map<String, String> mKeyValueache = new ConcurrentHashMap<String, String>();
    private Text result = new Text();

    public UDFKeyValue() {
    }

    public String evaluate(String str, String keyname){
        // The default value of split1 is a semicolon (;), and that of split2 is a colon (:).
        return evaluate(str, ";", ":", keyname);
    }

    public String evaluate(String str, String split1, String split2, String keyname) {
        try {   
                        // Use splitor1 to split the string to obtain key-value pairs.
            if (str == null || "".equals(str))
                return null;
            String[] values1 = str.split(split1);
            mKeyValueache.clear();
            int i = 0;
                        // Use splitor2 to split the obtained key-value pairs.
            while (i < values1.length) {
                storeKeyValue(values1[i], split2);
                i++;
            }
            String resultValue = getKeyValue(keyname);
            if (resultValue == null)
                return null;
            result.set(new Text(resultValue));
                        // Return the result.
            return result.toString();
        } catch (Exception e) {
            return null;
        }
    }

    private boolean storeKeyValue(String keyValues, String split) {
        if (keyValues == null || "".equals(keyValues))
            return false;
        if (mKeyValueache == null)
            mKeyValueache = new ConcurrentHashMap<String, String>();
        String[] keyValueArr = keyValues.split(split);
        if (keyValueArr.length == 2) {
            mKeyValueache.put(keyValueArr[0], keyValueArr[1]);
            return true;
        }
        return false;
    }

    private String getKeyValue(String keyName) {
        if (keyName == null || 
            "".equals(keyName) || 
            mKeyValueache == null || 
            mKeyValueache.size() == 0)
            return null;
        return mKeyValueache.get(keyName);
    }
}