0

I have a nested array I loop through every element in the array and read the value of key title then I check if the value includes a certain string if it includes the search string that value will be pushed to another array then I sort the new array by occurrence of the search string so that the index position of every element in the new array depends how similar the array element string is with the search string and also the array elements will be sorted by ascending letter order. Now this whole procedure works fine. What I want is once I get the sorted new array I want to loop though it then get the object containing the new arrays element as a title. How can I achieve this. Read the comments in my code to better understand my question. Thanks in advance.

note: When retrieving the object it should keep the index position of the newly created array.

const allArr = [
  [{
    "id": "1",
    "title": "blaha"
  }, {
    "id": "2",
    "title": "blahe"
  }, {
    "id": "3",
    "title": "dhs"
  }],
  [{
    "id": "4",
    "title": "blahc"
  }, {
    "id": "5",
    "title": "shg"
  }]
]

const searchTerm = 'blah'
let existsArr = []
let tempArr = []

for (var i = 0; i < allArr.length; i++) {
  const allAds = allArr[i]
  for (var j = 0; j < allAds.length; j++) {
    if (allAds[j].title.toLowerCase().includes(searchTerm.toLowerCase())) {
      existsArr.push(allAds[j].title)
    }
  }
}

tempArr = existsArr.filter(a => a.toLowerCase().includes(searchTerm))
const startsWith = (string, value) => string.substring(0, value.length).toLowerCase() === value

const sortByOccurance = JSON.stringify(tempArr.sort((a, b) => {
  const aStartsWith = startsWith(a, searchTerm)
  const bStartsWith = startsWith(b, searchTerm)

  if (aStartsWith && !bStartsWith) {
    return -1
  } else if (!aStartsWith && bStartsWith) {
    return 1;
  }

  return b > a ? -1 : 1
}))

console.log(sortByOccurance)

//now I want to get the object of every title found in sortByOccurance from allArr
//expected output: 
//[{"id": "1", "title": "blaha"}, {"id": "4", "title": "blahc"}, {"id": "2", "title": "blahe"}]

1 Answer 1

1

Array.flat flattens the array a level (or more). That makes it easier to find an item.title === term. So now we can loop over array and build our result array.

Update: not using Array.flat to allow for duplicate names with different id. Instead, we search for the first match (a "deep" search) and then delete it so next time will find next item.

const allArr = [
  [{
    "id": "1",
    "title": "blaha"
  }, {
    "id": "2",
    "title": "blahe"
  }, {
    "id": "3",
    "title": "dhs"
  }],
  [{
    "id": "4",
    "title": "blahc"
  }, {
    "id": "5",
    "title": "shg"
  }],
  [{
    "id": "6",
    "title": "blaha"
  }]
]

const searchTerm = 'blah'
let existsArr = []
let tempArr = []

for (var i = 0; i < allArr.length; i++) {
  const allAds = allArr[i]
  for (var j = 0; j < allAds.length; j++) {
    if (allAds[j].title.toLowerCase().includes(searchTerm.toLowerCase())) {
      existsArr.push(allAds[j].title)
    }
  }
}

tempArr = existsArr.filter(a => a.toLowerCase().includes(searchTerm))
const startsWith = (string, value) => string.substring(0, value.length).toLowerCase() === value

const sortByOccurance = JSON.stringify(tempArr.sort((a, b) => {
  const aStartsWith = startsWith(a, searchTerm)
  const bStartsWith = startsWith(b, searchTerm)

  if (aStartsWith && !bStartsWith) {
    return -1
  } else if (!aStartsWith && bStartsWith) {
    return 1;
  }

  return b > a ? -1 : 1
}))

function find_deep(arr, term) {
  for (var i = 0; i < arr.length; i++) {
    var value = arr[i]
    if (Array.isArray(value)) {
      var res = find_deep(value, term)
      if (res) {
        return res;
      }
    }
    if (value.title === term) {
      return value;
    }
  }
  return null;
}
console.log(sortByOccurance)


var result = [];

JSON.parse(sortByOccurance).forEach(function(term) {
  var found = find_deep(allArr, term)
  if (found) {
    result.push({ ...found
    })
    delete found.title; // <--- changes original allArr. 
  }
})

console.log(result)
.as-console-wrapper {
  max-height: 100% !important
}

Sign up to request clarification or add additional context in comments.

3 Comments

this will cause a problem if 2 objects with the same title exists
Define what needs to happen if two object with different id's have same title you're searching.
each title with 2 same title will have their own object with their own id. Take a look at this jsfiddle.net/#&togetherjs=HSrzJsfdvJ

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.