Unity Job System based Target Finding

Can someone help me to convert this to use Job System?

void FindNearestTarget()
{
    for (int i = 0; i < targetManager.TroopsArray.Length; i++)
    {
        shortestDistanceToTarget_sq = Mathf.Infinity;
        Transform nearestTarget = null;
        foreach (GameObject Target in targetManager.LootTargetsArray)
        {
            float distanceToTarget_sq = math.distancesq(targetManager.TroopsArray*.transform.position, Target.transform.position);
            if (distanceToTarget_sq < shortestDistanceToTarget_sq)
            {
                shortestDistanceToTarget_sq = distanceToTarget_sq;
                nearestTarget = Target.transform;
            }
        }
        if (nearestTarget != null)
        {
            targetManager.TroopsArray_.GetComponent<MovementH>().Movement((nearestTarget.position - targetManager.TroopsArray*.transform.position).normalized);
        }
    }
}

FindNearestTargetJob

[Unity.Burst.BurstCompile]
public struct FindNearestTargetJob : IJobParallelFor
{
    [ReadOnly] public NativeList<float3> Origins;// reads one per jobIndex
    [ReadOnly][NativeDisableParallelForRestriction] public NativeList<float3> Targets;// reads all per jobIndex
    [WriteOnly] public NativeArray<int> Results;
    void IJobParallelFor.Execute ( int jobIndex )
    {
        float3 origin = Origins[jobIndex];
        int candidate = -1;
        float candidateDistSq = float.PositiveInfinity;
        for( int i=0 ; i<Targets.Length ; i++ )
        {
            float distSq = math.distancesq( origin , Targets *);
            if( distSq<candidateDistSq )
            {
                candidateDistSq = distSq;
                candidate = i;
            }
        }
        Results[jobIndex] = candidate;
    }
}

find nearest target
Here is a full, working example based not on entities but common gameObjects.
(sourcing these positions from entities is a much easier case)

LetFindNearestTargets

// web* src = https://gist.github.com/andrew-raphael-lukasik/e9c3c1c85a149d2c041532e3632fe4e3
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Jobs;
using Unity.Mathematics;
using Unity.Jobs;
using Unity.Collections;
using Unity.Profiling;
 
public class LetFindNearestTargets : MonoBehaviour
{
	public List<Transform>
		troopsToAdd = new List<Transform>() ,
		troopsToRemove = new List<Transform>() ,
		targetsToAdd = new List<Transform>() ,
		targetsToRemove = new List<Transform>();
	TransformAccessArray _troopsDataAccess, _targetsDataAccess;
	NativeList<float3> _troopPositions, _targetPositions;
	NativeList<int> _nearestTargetIndices;
	public JobHandle Dependency;
	ProfilerMarker
		___proc_results = new ProfilerMarker("process job results") ,
		___maintain_data_access = new ProfilerMarker("maintan data access") ,
		___schedule_new = new ProfilerMarker("schedule jobs") ,
		___schedule = new ProfilerMarker("schedule calls");
	const float k_tick_rate = 0.4f;// tick every 0.4s
	void OnEnable ()
	{
		InvokeRepeating( nameof(Tick) , k_tick_rate , k_tick_rate );
		_troopsDataAccess = new TransformAccessArray( 32 );
		_targetsDataAccess = new TransformAccessArray( 32 );
		_troopPositions = new NativeList<float3>( 32 , Allocator.Persistent );
		_targetPositions = new NativeList<float3>( 32 , Allocator.Persistent );
		_nearestTargetIndices = new NativeList<int>( 32 , Allocator.Persistent );
	}
	void OnDisable ()
	{
		CancelInvoke();
		Dependency.Complete();
		if( _troopsDataAccess.isCreated ) _troopsDataAccess.Dispose();
		if( _targetsDataAccess.isCreated ) _targetsDataAccess.Dispose();
		if( _troopPositions.IsCreated ) _troopPositions.Dispose();
		if( _targetPositions.IsCreated ) _targetPositions.Dispose();
		if( _nearestTargetIndices.IsCreated ) _nearestTargetIndices.Dispose();
	}
	#if UNITY_EDITOR
	void OnDrawGizmos ()
	{
		if( !Application.isPlaying ) return;
		Gizmos.color = Color.blue;
		for( int i=_troopsDataAccess.length-1 ; i!=-1 ; i-- )
 			Gizmos.DrawWireCube( _troopsDataAccess*.position , Vector3.one );
		Gizmos.color = Color.red;
		for( int i=_targetsDataAccess.length-1 ; i!=-1 ; i-- )
 			Gizmos.DrawWireSphere( _targetsDataAccess*.position , 1f );
	}
	#endif
	void Tick ()
	{
		Dependency.Complete();
 
		// process results
		___proc_results.Begin();
		{
			// don't do this like I'm doing here, it's just for quick & dirty viz
			// i.e. avoid reading/writing from native collection outside jobs, it very slow (especially in big loops)
 
			int numResults = _nearestTargetIndices.Length;
			for( int i=0 ; i<numResults ; i++ )
			{
 				int nearestTargetIndex = _nearestTargetIndices*;
 				Debug.DrawLine( _troopPositions *, _targetPositions[nearestTargetIndex] , Color.yellow , k_tick_rate );
 				// Transform troop = _troopsDataAccess*;
				// Transform target = _targetsDataAccess[nearestTargetIndex];
			}
		}
		___proc_results.End();
 
		// TransformAccessArray maintainance
		___maintain_data_access.Begin();
		{
			int numTroopsToRemove = troopsToRemove.Count;
			if( numTroopsToRemove!=0 )
			{
				for( int i=0 ; i<numTroopsToRemove ; i++ )
				{
					Transform next = troopsToRemove*;
					if( next!=null )
					for( int k=_troopsDataAccess.length-1 ; k!=-1 ; k-- )
					{
						if( _troopsDataAccess[k]==next )
						{
							_troopsDataAccess.RemoveAtSwapBack( k );
							break;
						}
					}
				}
				troopsToRemove.Clear();
			}
 
			int numTroopsToAdd = troopsToAdd.Count;
			if( numTroopsToAdd!=0 )
			{
				for( int i=0 ; i<numTroopsToAdd ; i++ )
					if( troopsToAdd*!=null )
 						_troopsDataAccess.Add( troopsToAdd *);
				troopsToAdd.Clear();
			}
 
			int numTargetsToRemove = targetsToRemove.Count;
			if( numTargetsToRemove!=0 )
			{
				for( int i=0 ; i<numTargetsToRemove ; i++ )
				{
					Transform next = targetsToRemove*;
					if( next!=null )
					for( int k=_targetsDataAccess.length-1 ; k!=-1 ; k-- )
					{
						if( _targetsDataAccess[k]==next )
						{
							_targetsDataAccess.RemoveAtSwapBack( k );
							break;
						}
					}
				}
				targetsToRemove.Clear();
			}
 
			int numTargetsToAdd = targetsToAdd.Count;
			if( numTargetsToAdd!=0 )
			{
				for( int i=0 ; i<numTargetsToAdd ; i++ )
					if( targetsToAdd*!=null )
 						_targetsDataAccess.Add( targetsToAdd *);
				targetsToAdd.Clear();
			}
		}
		___maintain_data_access.End();
 
		// schedule new jobs:
		___schedule_new.Begin();
		int numTroops = _troopsDataAccess.length;
		int numTargets = _targetsDataAccess.length;
		if( numTroops!=0 && numTargets!=0 )
		{
			___schedule.Begin();
			_troopPositions.Length = numTroops;
			_nearestTargetIndices.Length = numTroops;
			_targetPositions.Length = numTargets;
 
			JobHandle troopPositionsJobHandle = new ReadPositionsJob{ Results = _troopPositions }
				.Schedule( _troopsDataAccess );
			JobHandle targetPositionsJobHandle = new ReadPositionsJob{ Results = _targetPositions }
				.Schedule( _targetsDataAccess );
 
			var findNearestTargetJob = new FindNearestTargetJob
			{
				Origins = _troopPositions ,
				Targets = _targetPositions ,
				Results = _nearestTargetIndices ,
			};
			Dependency = JobHandle.CombineDependencies( troopPositionsJobHandle , targetPositionsJobHandle , Dependency );
			Dependency = findNearestTargetJob.Schedule(
				arrayLength:			numTroops ,
				innerloopBatchCount:	math.max( numTroops/SystemInfo.processorCount/4 , 1 ) ,
				dependsOn:				Dependency
			);
			___schedule.End();
		}
		___schedule_new.End();
	}
}
 
[Unity.Burst.BurstCompile]
public struct ReadPositionsJob : IJobParallelForTransform
{
	[WriteOnly] public NativeArray<float3> Results;
	void IJobParallelForTransform.Execute ( int index , TransformAccess transform )
		=> Results[index] = transform.position;
}