Programmatically setting a link
The hook you're looking for is hook_views_view_field().

This hook allows you to alter the output of the field, and still is early enough to have the entity data for for that field.

In the example below, I'm checking if the node has a link field, field_my_link set, and if it's set, I alter the title output (which is normally linked to the node) to output to the link field's uri, but only if it's an external link.

function mymodule_preprocess_views_view_field(&amp;$vars) {
  if ($vars['view']-&gt;id() != 'testview') {
    return;
  }
  $node = $vars['row']-&gt;_entity;
  if ($vars['field']-&gt;getField() == '.title' &amp;&amp; $node-&gt;field_my_link-&gt;isEmpty() === FALSE) {
    if ($node-&gt;field_my_link[0]-&gt;isExternal()) {
      $link = $node-&gt;field_my_link[0]-&gt;view();
      $link['#title'] = $node-&gt;label();
      $vars['output'] = $link;
    }
  }
}


If you want to alter the output of one views field based on the output of another, use hook_views_view_fields():

function mymodule_preprocess_views_view_fields(&amp;$vars) {
  if ($vars['view']-&gt;id() != 'testview') {
    return;
  }

  // Cast Markup object to string.
  $field_one_content = (string) $vars['fields']['field_1']-&gt;content;

  // Check if first field contains a substring, if so, update second field.
  if (strpos($field_one_content, 'my search string') &gt; -1) {
    $vars['fields']['field_2']-&gt;content = \Drupal\Core\Render\Markup::create('hello world');
  }

}