Home > Enterprise >  Split an array based on whether the elements occur in another array or not
Split an array based on whether the elements occur in another array or not

Time:07-27

*I don't know what's the proper title should be. But I will explain my problem clearly.

In this situation, I have two arrays

oldIDs = [1, 2]
newIDs = [2, 3, 4]

question:
how to split "newIDs" into [[2], [3,4]] ?

explanation:
2 is an old id (It is existed in oldIDs)
3 & 4 are new ids (which are not existed in oldIDs)


Other examples:

oldIDs = [1]
newIDs = [1, 2]
// the result should be [[1], [2]]

oldIDs = [1, 3, 5]
newIDs = [3, 4, 7, 8]
// the result should be [[3], [4, 7, 8]]

This is what I'm doing with Go.

func splitIDs(oldIDs []int64, newIDs []int64) (arr1 []int64, arr2 []int64) {
    for _, newID := range newIDs {
        if contains(oldIDs, newID) {
            arr1 = append(arr1, newID)
        }
    }
    for _, newID := range newIDs {
        if !contains(oldIDs, newID) {
            arr2 = append(arr2, newID)
        }
    }
    return
}

func contains(a []int64, x int64) bool {
    for _, n := range a {
        if x == n {
            return true
        }
    }
    return false
}

This can also be divided into two arrays, not necessarily two dimensional array.

I really appreciate someone who can solve my problem or improve my solution.

CodePudding user response:

Below is a program in python.
This first read through old id, creates a dictionary out of it. and read through the new ids looking for common number, to split.

oldIDs = [1, 3, 5]
newIDs = [3, 4, 7, 8]

def split(oldIDs,newIDs):
    o_dict={}
    for i in oldIDs:
        o_dict[i]=True
    for i,num in enumerate(newIDs):
        if num in o_dict:
            return [newIDs[:i 1],newIDs[i 1:]]

print(split(oldIDs,newIDs))

CodePudding user response:

You can get the arrays intersection and the arrays difference and combine them into one array as follows:

const oldIDs = [1, 3, 5]
const newIDs = [3, 4, 7, 8]

const splitArray = (arr1, arr2) => {
  const result = []
  //Getting the arrays intersection
  result[0] = arr2.filter((item) => {
    return arr1.includes(item)
  })
  //Getting the arrays difference
  result[1] = arr2.filter((item) => {
    return !arr1.includes(item)
  })
  return result
}

console.log(splitArray(oldIDs, newIDs))

CodePudding user response:

It turns out there is a library (not surprisingly) for this same purpose. It is split_into available in more_itertools

All you need to do is:

res = list(more_itertools.split_into(newIDs, oldIDs   [None]
           * (len(newIDs) - len(oldIDs))))

res = list(filter(lambda x: len(x) > 0, res))

Otherwise if you want to write your own loop ( which I prefer ):

def split_newIDs(oldIDs, newIDs):
    i = 0
    j = 0
    res = []
    while i < len(newIDs):
        res.extend([newIDs[i:i   oldIDs[j]]])
        i  = oldIDs[j]
        if j < len(oldIDs) - 1:
            j  = 1
    return res


print split_newIDs(oldIDs, newIDs)

What is this doing is, keep checking if you have seen all elements in newIDs but also keeping a check on the index in your oldIDs so that you keep using the oldIDs if you fall short.

You can use this to run the code.

  • Related